谈谈设计之「自顶向下」和「自底向上」

谈谈设计之「自顶向下」和「自底向上」


今天在做一个技术评审的时候,同事在讲设计,设计图画得不清楚,后面讲着讲着就说“还是来看(demo)代码吧”。另一个同事觉得看设计不要看代码,要把设计用图来体现,更清晰。

由此我想到了两种设计方法,即标题的「自顶向下」和「自底向上」,「Top-Down」和「Bottom-Up」,也有讲「自上而下」和「自下而上」。

先来看看这两种设计方法。

「自顶向下」是从抽象到具体,即从高层次的抽象开始,向下进行拆分,直到具体的细节。我们常说的「分而治之」就是这种思路。

举一个生活中的例子来帮助理解,比如,我们订个人的年度计划。

首先我要确定关注在家庭、财务、学习和工作四个方面;

然后针对家庭方面再拆解,家庭外出活动x次,比如看电影、游乐场,陪孩子…

针对财务方面,要存多少钱、置备哪些家具…

针对学习方面,要提升哪几方面…

再拆解,比如学习,要提升职业规划能力、设计能力、编码能力…

再拆解,针对学习的提升职业规划能力,要看x本书,书单列出来…

这样,个人年度计划就订出来了,最后可以用一张脑图来描述,每个末端节点都可以执行,这样就是使用「自顶向下」的设计方法设计了「个人年度计划」。

这种设计思路实际上是有这样一个指导原则:人的大脑在同一时间只能集中关注一定量的细节。通过持续迭代,一层层的分解,直到某一层的细节已经显而易见,这样就把整个系统设计好了。比如前面,某个方面的学习内容分解到看哪几本书,基本就差不多了。

而「自底向上」是相反的,从具体到抽象。从细节开始,把这些细节组合起来,逐渐设计出一个通用的系统。这其实比较符合一些程序员的思路,比较实在。

也举一个生活的例子来帮助理解。比如,你家住在山脚下,明天要去山林里砍一些木头回家当柴火。

可能会这么做,看看手头有哪些工具:扳手、斧子、磨刀石、菜刀、木桶、篓子、绳子、书、笔、脸盆、自行车、大客车、小推车…

拿出磨刀石,磨斧子;

然后把斧子、小推车、绳子、水杯、面包选出来放好,准备一早出发;

这个砍柴的设计就结束了。这就是「自底向上」,从可控的部分出发,达成目标。

在程序员的世界,说到另外一个词,就好理解「自底向上」了,那就是「重构」。有一些敏捷实践和精益实践也是这样的。先以当前对问题的认识,快速用已有的资源做一个出来,满足需求。然后再把某些有共性的东西抽出来,或者把有问题的地方隔离出来,这样逐渐迭代,系统也会趋于完备。

下面来比较一下这两种设计方法。

说「自底向上」这种设计思路比较实在,是因为它通常能够较早的找出能做的,尽早验证,能够让系统更紧凑,在某些时候更容易快速的达成目标。

而「自顶向下」在这方面可能有细节搞不定的风险,那就惨了。比如「给我一个支点,我就能撬动地球」,问题是支点找不到啊。再比如上面那个年度计划的例子,最后分解出每年看200本书,但按自己从前的经验只能看20本书来评估,那么这可能就是一个注定完不成的计划了。

当然,程序员的「技术预研」就是在这种设计思路上的底层细节保证,通过提前验证可行性,来规避这些问题的,所以说为啥有些不是很清楚的问题,技术预研是很关键的。

「自底向下」从可控的出发,但有最终搞不定目标的风险,可能有时候不知道从哪里开始研究。比如,有一堆砖块,很难想象怎么去造飞机,还是得要先做高层设计,再考虑怎么优化材料。

「自顶向下」容易从宏观理清问题和解决方案,推迟细节的影响,更好评估,设计相对比较简单(完全实现就不一定了)。

「自顶向下」与「自底向上」,也可以看作是「演绎」与「归纳」的分析方式,还可以看作是「分解」和「合成」的策略。

设计是一个启发式的过程,没有任何解决方案是完美的,「没有银弹」。在实际中,设计一个系统,会结合二者,这是比较合适的做法。

大局观和细节,缺一不可。

当然,在给别人讲解技术方案或者思路的时候,通常先隐藏一些细节,更容易理解。讲清楚整体,再分析局部。所以架构图还是要画清晰的。

© 2024 lyremelody.cn All Rights Reserved
访问量: