CSharp小练习0001,有奖代码逻辑趣味小练习 这个练习,许多同学都进行了练习提交了解答。
不管你做没做对,你开始注意:原来写代码,要时刻关注自己写这段代码时的思维方式。
只有养成这样的习惯,你写代码时才会经常去修改,并且反思换一种思维方式,是不是就能解决之前解决不了的,或者解决得更好。
而我们这次练习的目的就是:把习惯性的进入if,else的分支,改成一条线往下执行的逻辑,其中的if语句也成了线上的一个点(不再是切换的分支)
☂当然不是说if,else不好,都要改成线性逻辑。而是要时刻保持尝试灵活变换思维,不要被习惯困住。这个练习的情况就是适合,方便做到写成线性,最下面还有示例的情况更是适合。
🚩练习的答案是:
public static SceneConfig GetMapScene(GateAccount gateAccount, int mapNum, uint zoneId)
{
var mapSceneId = gateAccount.GetMapSceneId(mapNum);
if (mapSceneId == 0)
{
// 如果没有登录此地图的记录,随机选择一个地图配置
var mapScene = SceneHelper.GetSceneRandom(SceneType.Map, zoneId);
// 不用存库,在维护周期内在GateAccount记住此地图登录的是这个mapScene
gateAccount.MapSceneIds.Add(mapNum, mapScene.Id);
return mapScene;
}
return SceneConfigData.Instance.Get(mapSceneId);
}
几种典型的思维方式:
- 有限分支思维
if,else就是有限分支思维,这种用的最多,但是你要知道,每一次分支,就意味着所有相关的逻辑,从此都要考虑两种情况(是不是经常忘记,然后要靠debug后,才开始加上之前忘记考虑的受关联逻辑分支)
- 无限分支思维
swtich就是无限分支思维,相对于if,else 它更安全一些,因为既然这样写,就是考虑到有n种分支,后续可能还会再加。所以可以认为这是一种主动条理化的分支思维
。
- 线性思维
去除分支就是线性思维,有许多情况的有限分支是可以线性化的,这就要求我们换一种思维方式来思考逻辑,这能把你从分支逻辑纠缠
中解救出来。下面有代码示例,你印象会更深刻。
- 正向思维
自然习惯的执行方向,就是正向思维。
比如服务器上广播消息,遍历所有的用户,一一发消息给他们,这就是典型的正向思维。但正向思维的问题就是不管这消息与你有没有关,或你此时的状态需不需要,都得发给你。
同样是达到广播消息的效果,反过来可以是在服务器上每个玩家的unit上加一个状态同步组件,
他不停的收集他关注的消息,15帧的间隔把上一个间隔收集到的消息发给自己的客户端就可以了。
这样不需要遍历所有的玩家,一样所有的玩家都能收到消息。
当他处于不可收到消息的状态时,还可以把unit上的同步组件移除。
这就是正向思维不合适或者做不到的。
有限分支线性化示例:
看看下面的写法,如果用分支思维写,结果是一样的,但思考起来会很费劲:
除了有本方法体中的分支外,还受到IsAccountValid(),IsPasswordValid()外部方法中分支的影响。
下面代码中使用线性思维,把多层分支拉平成了一条线往下执行。
主体方法中就一条线,还把外部方法的返回结果,也接到了这条线上。
// 版本号不一致
if (request.Version != ConstValue.Version)
return ErrorCode.H_A2C_Login_Res_VersionERROR;
// 账号校验
var err = authName.IsAccountValid();
if (err != ErrorCode.Success)
return err;
// 密码校验
err = pw.IsPasswordValid();
if (err != ErrorCode.Success)
return err;
主动条理化n分支示例:
这种就适合switch ,意思是准备好可能有n种类型的服务器的,这里把逻辑主动准备好条理。
你需要更多服务器类型就在下面加分支,不需要还可以减。
是不是用if,else也可以写?但就显得没这么有条理,也不像是有n种分支,是事先就考虑到并准备在这里的。
public override async FTask Handler(Fantasy.OnCreateScene self)
{
var scene = self.Scene;
switch (scene.SceneType)
{
case SceneType.Addressable:
{
// 挂载管理Address地址组件
scene.AddComponent<AddressableManageComponent>();
break;
}
case SceneType.Mgr:
{
scene.AddComponent<ServerMgr>();
break;
}
case SceneType.Gate:
{
// 网关sessionKey组件
scene.AddComponent<SessionKeyComponent>();
break;
}
case SceneType.Map:
{
// Unit管理组件
scene.AddComponent<UnitComponent>();
break;
}
case SceneType.Realm:
{
// 认证帐号管理组件
scene.AddComponent<AccountManager>();
break;
}
}
await FTask.CompletedTask;
}
示例代码源自Fantasy框架作者 @初见 的项目