仓库源文

.. Kenneth Lee 版权所有 2017-2020

:Authors: Kenneth Lee :Version: 1.0

“设计的流程”和“代码的流程”


有时很矛盾,我很反对别人把代码的流程搬到文档中,但我又经常反对别人不写设计文档 就去写代码。这里面有个很微妙的差别。我以前说过,代码本身就是设计。但它有时不如 用文档写的设计。这里核心的差别是,文档写的设计忽略细节。

“忽略细节”就可以关注到问题的核心,这些核心我认为包括:

  1. 数据结构被限制在什么范围内访问

  2. 行为被限制在什么模块内完成

  3. 内部推演后,能否在对外表现为一致的行为

比如我有个分层的代码构架是这样的:

    .. figure:: _static/分层架构.png

这种程序在构建阶段很容易乱掉的,因为如果直接写代码,你很容易顺着“流程”来构建, 比如,你要创建一个结构用来存放用户请求,这个结构谁来分配?里面的成员哪部分可以 让用户程序看到,哪部分可以让功能框架看到?其中一层要看另一层的信息,通过什么手 段来获得?如果你不从这个架子上来考虑这个流程,你的构建很容易变成很随意(反正都 能跑),但能你加入更多的驱动的时候,你就发现你又多了多少重复代码,或者索引不够 了,等等等等一类的问题。

当然,我们一种常见的方法是先写一个驱动,然后通过增加第二个驱动来“暴露”冗余代码 ,从而慢慢把框架调整好。但这种方式不能作为根本手段,因为实际上大部分真实的代码 的复杂度都非常高,等你进行调整的时候,你已经浪费巨大的编码和调试的工作量了。

所以我们就要通过几个关键的流程的设计定义,来控制主运行流程的过程,比如我会这样 写(懒得画图,我用列表形式表达):

关联流程:

  1. (用户程序)根据功能id发起请求

  2. (功能框架)直接向内核功能框架请求功能

  3. (内核功能框架)查找所有注册驱动的,看谁能提供该功能

  4. (内核驱动)被匹配的驱动通过调用内核功能框架的函数建立句柄

  5. (内核功能框架)返回句柄

这样,大概我们就控制住几个关键模块的功能范围了,至于内核功能框架和内核驱动之间 用什么方法来实现查找,这个你用链表还是数组还是Hash,它总是能搞定的,在代码的时 候你需要考虑这个问题,在设计的时候引入这种逻辑,就破坏了设计的本来目的了。

所以,设计文档,做个样子是没有用的,你得真打算设计点什么。把代码拷贝回来,还不 如不写。