我用这一招教会了老婆《状态机》——程序员与非程序员必看
人物介绍:
- 我——小D
- 我老婆——小Q
搬好小板凳开始了……
小Q:“帮我拿下……”
小D:聚精会神的看着手机……
小Q:“喂!帮我拿下……”
小D:继续聚精会神的看着手机……
小Q:“听讲没有,XXXXXXXXXXXXX”
小D:我做错了什么?我咋了?懵逼……
小Q:老娘都这么生气了,你还啥都没事一样,更生气……:“XXXXXX”
小D:完了,老婆生气了……赶紧哄哄
终于说了一个小时的甜言蜜语外加两张洗碗卡把老婆哄的开心了。小D终于可以松口气,其实脑海中还在那想着写一系列文章讲《 状态机 》,还想把它讲的通俗一点。
小D:“老婆你还生气不了?”
小Q:“不生了,最爱你了……”(这句虽然是我自己加上的,可我知道你心里是这么想的)
小D:嘿嘿,有了。最通俗的就是把一些难理解的东西和已经理解的东西挂上钩,借用已经有的经验来解释不明白的事情。既然老婆刚生完气,还不懂状态机,那我就用“生气”来给她讲讲。
小D:“老婆,有时候你会生气,有时候我会生气,不过我们最后都开开心心的。等会儿没事儿给咱俩从生气到最终怎么和好的一起画张图吧”
小Q:“?…………?”
小D:“相信我,你会学到一些新东西,你们财务天天流程那么多,这东西在你工作繁杂程序理不顺的时候还可以帮你”
小Q:“那好吧”
小D:嘿嘿嘿……
转场,两个人坐在那拿着pad开始商量怎么画了
小D:“你看我们正常的时候是不是都开开心心的,然后突然莫名其妙的你就生气了”
小Q:“什么莫明奇妙,明明就是你欠揍,不理我好不”
小D默念:不敢抬杠,不敢抬杠,要不肯定图还没开始又要生气了。“嘻嘻,你优秀的老公不是在思考如何变得更优秀来配的上你吗?”
“你看,开开心心是我们正常的状态,当我不理你的时候你就生气了”
这幅图终于画起来了
小Q:“有时候你不也会生气”
小D:“哼,还不是你吼我”
小D:“还有种情况,你每次先生气,再吼我我也会很生气”。有时候你生气过一会儿就又被我哄的开心了
小Q:“哦”
小D:“我想想我们俩生气最严重的的时候是什么情况”
小Q:“这辈子再也不想理你!”
小D:“哦,I see!”
小D:“吵的严重的时候我们都那么生气,那时候最后又咋和好的呢”
小Q:沉默……
小D:“你沉默我都不知道了?我想起来了,每一次都是一样的场景”
小D:“想想都生气!有时候俩人都生气好像也没那么严重,冷静过一会儿又好了”
小Q:“才不想跟你和好!”
小D:“现在看起来清晰明了,哼!不画不知道,一画吓一跳,我终于知道为啥最后我们都和好了!”
小Q:“为啥?”
小D:“你看,所有指向开心状态线条上的蓝色条件都是啥:哄小Q,哄小Q,哄小Q睡。原来都是我把你哄好的”
小Q:“哈哈哈,那你要一直哄我!”
小D:“哦嘛噶,我又明白了,原来我们经常保持开心状态就是我一直在哄你!!!!!”
小Q:“你怎么那么优秀呢!gagaga~~~”
然后,小D默默的在开开心心的圆圈外面又画了一条指向自己的线……
后传
小D:“这就是状态图,描述这个问题的模型就是状态机,是不是我们生气这么复杂的流程被状态图画出来就很明了了。每一个状态都可以跳转到其他状态,而蓝色字的描述就是触发条件,达到了这个条件就会进行状态转移,这样我们最终才能又回到了开心的状态。”
小D:“你工作里面那么多理不顺的事情,你就用状态机把事情的状态和转移条件画出来,这样所有状态和转移条件描述完了,整个流程你就理顺了,处理起来也不会晕晕乎乎!”
小Q:“我懂了!么么哒!”
写给程序员:
我一直觉得其实很多代码中解决问题的模型都可以从生活中来获取,反过来有些在代码中解决问题的思想也可以用在生活中。
我们继续聊生气这个状态模型,这样的图画出来,你写代码的思路是不是就清晰,在出现异常问题(生气)的时候该如何处理,最后才能恢复到正常的状态一目了然。现在让我们用一些不严谨的代码来把模型描述出来,当描述完的时候你的代码就写好了,可以进行测试了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
void let_wife_happy() { uint8_t 状态; while(1) { switch (状态) { case 开开心心: if(小D不理小Q)状态=小Q生气; else if(小Q吼小D)状态=小D生气; else if(一直哄)状态=开开心心; else 状态=小Q生气; break; case 小Q生气: if (哄小Q)状态=开开心心; else if(吼小D)状态=小D生气; case 小D生气: if (发酵)状态=俩人生气; break; case 俩人生气: if(等10分钟)状态=俩人平静; else if(吵起来)状态=冷战; break; case 两人平静: if (哄小Q)状态=开开心心; break; case 冷战: if (踢小D下床)状态=两人谈心; break; case 俩人生气: if (哄小Q)状态=开开心心; break; default: break; } } } |
关于状态机更深层讨论
醒醒,别只沉浸在开开心心的状态中。咱再进行一些技术层面更深层次的探讨。再往更抽象的一层看,如上所示的状态机主要解决了什么问题,这种生气的场景和在开发中的哪些场景有点类似?
状态机主要解决了什么问题
最重要的就是把错综复杂的问题先进行建模进行梳理。在开发过程中,但不仅仅限于嵌入式软件开发,针对某一个问题处理可能出现很多种可能,如果想到一种可能就写一点代码,不把自己写晕进去才怪。最后写过去的自己都不知道写的啥。比如一个wifi联网设备,从上电初始化——》连接路由器——》连接服务器——》给服务器发送数据——》收到服务器返回数据——》进入低功耗模式。
从整体来思考流程不就是一个个状态的转移,借助状态机建模把整个流程切分成一个个状态。当然在大框架下,可能还能细分出来一个个小的状态机模型,比如初始化里面可能还有很多个步骤,可以把这些步骤再用一个状态机来描述。 当你把所有流程理清了。写代码只是最后最容易的一步。
生气的场景和开发中哪些场景类似?
在嵌入式开发中,一个功能开发好的产品有时候为什么会出bug。归根结底就是对异常情况的处理。如果保证一直都是正常的情况,一直运行当然没问题。但是总会出现一些异常(就像例子中的“生气了”)。就比如wifi联网设备,连接服务器过程中和路由器断电了,是不是异常?给服务器发送数据没收到服务器返回数据是不是异常?
而我们用状态机建模就可以把能想到的所有异常的状态都描述出来,最终通一定的条件转移让系统修复回归到正常的状态。
最后
感谢我家小孬倩给提供这么好的素材,还有配合我来画图!
欢迎关注我的微信公众号:电子创客营,随时看我们的最新原创技术文章!