1【强制】存储方案和底层数据结构
存储方案和底层数据结构的设计需要获得评审一致通过,并沉淀为文档。
说明:有缺陷的底层数据结构容易导致系统风险上升,可扩展性下降,重构成本也会因历史数据迁移和系统平滑过渡而突然增加。所以,存储方案和数据结构需要认真地进行设计和评审,生产环境提交执行后,需要进行 二次检查。
# 正例
评审内容包括存储介质、
表结构设计能否满足技术方案、
存储性能和存储空间能否满足业务发展、
表活字段之间的辩证关系、字段名称、字段类型、索引等;
数据结构变更(如在原有表中新增字段),也需要进行评审通过后上线。
2【强制】业务多状态
如果某个业务对象的状态超过3个,使用状态图来表达并且明确状态变化的各个触发条件。
说明:状态图的核心是对象状态,首先明确对象有多少种状态,然后明确两两状态之间是否存在直接转换关系,在明确触发状态的条件是什么。
# 正例
淘宝订单状态有:已下单、待付款、已付款、待发货、已发货、已收货等。
比如:已下单与已收货这两种状态之间是不可能有直接转换关系的。
3【强制】功能链路涉及对象超过3个时
当功能链路涉及对象超过3个时,使用时序图来表达并且明确各调用环节的输入与输出。
说明:时序图反应了一系列对象的交互与协作关系,清晰立体地反应系统的调用纵深链路。
4【推荐】需求分析考虑主干功能,同时考虑异常与业务边界
需求分析与系统设计在考虑主干功能的同时,需要充分评估异常流程与业务边界。
# 反例
用户在淘宝付款过程中,银行扣款成功,发送给用户扣款成功短信,但是支付宝入款时由于断网演练产生异常,淘宝订单页面依然显示未付款,导致用户投诉。
5【推荐】类在设计与实现时要符合单一原则
说明:单一原则最易理解,确是最难实现的一条规则,随着系统演进,很多时候,忘记了类设计的初衷。
6【推荐】谨慎使用继承的方式进行扩展
说明:不得已使用继承的话,必须符合里氏代换原则,此原则说父类能够出现的地方,子类一定能够出现。
比如:“把钱叫出来”,前的子类包括人民币、美元、欧元等都可以出现。
7【推荐】尽量依赖抽象类与接口
说明:低层次模块依赖于高层次模块的抽象,方便系统间的解耦。
8【推荐】线上代码不可改
说明:在极端情况下,交付上线生产环境的代码都是不可修改的,同一业务域内的需要变化,通过模块或类的扩展来实现
9【推荐】封装公共代码
系统设计阶段,共性业务或公共行为抽取出来公共模块、公共配置、公共类、公共方法等,避免出现重复代码或重复配置的情况。
说明:随着代码的重复次数不断增加,维护成本指数级上升。
10【推荐】避免如下误解:敏捷开发=讲故事+编码+发布
**说明:**敏捷开发是快速交付迭代可用的系统,沈略多余的设计方案,摒弃传统的审批流程,但核心关键点上的必要设计和文档沉淀是需要的。
# 反例
某团队为了业务的快速发展,敏捷成了产品经理催进度的接口,系统中均是勉强能运行,但像面条一样的代码,可维护性和可扩展性极差,一年之后,不得不进行大规模重构,得不偿失。
11【参考】系统设计主要目的
系统设计主要目的是明确需求、理顺逻辑、后期维护,次要目的用于指导编码。
**说明:**避免为了设计而设计,系统设计文档有助于后期的系统维护和重构,所以设计结果需要分类归档保存。
12【参考】设计的本质
设计的本质是识别和表达系统难点,找到系统的变化点,并隔离变化点。
说明:在众多设计模式中,目的均为隔离系统变化点。
13【参考】系统架构设计的目的
- 确定系统边界。确定系统在技术层面上的做与不做。
- 确定系统内模块之间的关系。确定模块之间的依赖关系及模块的宏观输入和输出。
- 确定指导后续设计与烟花的原则。使后续的子系统或模块设计在规定的框架内继续演化。
- 确定非功能性需求。非功能性需求是指安全性、可用性、可扩展性等。
<h2><a id="1_0"></a>1【强制】存储方案和底层数据结构</h2>
<p>存储方案和底层数据结构的设计需要获得评审一致通过,并沉淀为文档。</p>
<p>说明:有缺陷的底层数据结构容易导致系统风险上升,可扩展性下降,重构成本也会因历史数据迁移和系统平滑过渡而突然增加。所以,存储方案和数据结构需要认真地进行设计和评审,生产环境提交执行后,需要进行 二次检查。</p>
<pre><div class="hljs"><code class="lang-shell"><span class="hljs-meta"># </span><span class="language-bash">正例</span>
评审内容包括存储介质、
表结构设计能否满足技术方案、
存储性能和存储空间能否满足业务发展、
表活字段之间的辩证关系、字段名称、字段类型、索引等;
数据结构变更(如在原有表中新增字段),也需要进行评审通过后上线。
</code></div></pre>
<h2><a id="2_15"></a>2【强制】业务多状态</h2>
<p>如果某个业务对象的状态超过3个,使用状态图来表达并且明确状态变化的各个触发条件。</p>
<p>说明:状态图的核心是对象状态,首先明确对象有多少种状态,然后明确两两状态之间是否存在直接转换关系,在明确触发状态的条件是什么。</p>
<pre><div class="hljs"><code class="lang-shell"><span class="hljs-meta"># </span><span class="language-bash">正例</span>
淘宝订单状态有:已下单、待付款、已付款、待发货、已发货、已收货等。
比如:已下单与已收货这两种状态之间是不可能有直接转换关系的。
</code></div></pre>
<h2><a id="33_27"></a>3【强制】功能链路涉及对象超过3个时</h2>
<p>当功能链路涉及对象超过3个时,使用时序图来表达并且明确各调用环节的输入与输出。</p>
<p>说明:时序图反应了一系列对象的交互与协作关系,清晰立体地反应系统的调用纵深链路。</p>
<h2><a id="4_33"></a>4【推荐】需求分析考虑主干功能,同时考虑异常与业务边界</h2>
<p>需求分析与系统设计在考虑主干功能的同时,需要充分评估异常流程与业务边界。</p>
<pre><div class="hljs"><code class="lang-shell"><span class="hljs-meta"># </span><span class="language-bash">反例</span>
用户在淘宝付款过程中,银行扣款成功,发送给用户扣款成功短信,但是支付宝入款时由于断网演练产生异常,淘宝订单页面依然显示未付款,导致用户投诉。
</code></div></pre>
<h2><a id="5_42"></a>5【推荐】类在设计与实现时要符合单一原则</h2>
<p>说明:单一原则最易理解,确是最难实现的一条规则,随着系统演进,很多时候,忘记了类设计的初衷。</p>
<h2><a id="6_46"></a>6【推荐】谨慎使用继承的方式进行扩展</h2>
<p>说明:不得已使用继承的话,必须符合里氏代换原则,此原则说父类能够出现的地方,子类一定能够出现。</p>
<p>比如:“把钱叫出来”,前的子类包括人民币、美元、欧元等都可以出现。</p>
<h2><a id="7_52"></a>7【推荐】尽量依赖抽象类与接口</h2>
<p>说明:低层次模块依赖于高层次模块的抽象,方便系统间的解耦。</p>
<h2><a id="8_56"></a>8【推荐】线上代码不可改</h2>
<p>说明:在极端情况下,交付上线生产环境的代码都是不可修改的,同一业务域内的需要变化,通过模块或类的扩展来实现</p>
<h2><a id="9_60"></a>9【推荐】封装公共代码</h2>
<p>系统设计阶段,共性业务或公共行为抽取出来公共模块、公共配置、公共类、公共方法等,避免出现重复代码或重复配置的情况。</p>
<p>说明:随着代码的重复次数不断增加,维护成本指数级上升。</p>
<h2><a id="10_66"></a>10【推荐】避免如下误解:敏捷开发=讲故事+编码+发布</h2>
<p>**说明:**敏捷开发是快速交付迭代可用的系统,沈略多余的设计方案,摒弃传统的审批流程,但核心关键点上的必要设计和文档沉淀是需要的。</p>
<pre><div class="hljs"><code class="lang-shell"><span class="hljs-meta"># </span><span class="language-bash">反例</span>
某团队为了业务的快速发展,敏捷成了产品经理催进度的接口,系统中均是勉强能运行,但像面条一样的代码,可维护性和可扩展性极差,一年之后,不得不进行大规模重构,得不偿失。
</code></div></pre>
<h2><a id="11_75"></a>11【参考】系统设计主要目的</h2>
<p>系统设计主要目的是明确需求、理顺逻辑、后期维护,次要目的用于指导编码。</p>
<p>**说明:**避免为了设计而设计,系统设计文档有助于后期的系统维护和重构,所以设计结果需要分类归档保存。</p>
<h2><a id="12_81"></a>12【参考】设计的本质</h2>
<p>设计的本质是识别和表达系统难点,找到系统的变化点,并隔离变化点。</p>
<p><strong>说明:<strong>在众多设计模式中,目的均为</strong>隔离系统变化点</strong>。</p>
<h2><a id="13_87"></a>13【参考】系统架构设计的目的</h2>
<ul>
<li>确定系统边界。确定系统在技术层面上的做与不做。</li>
<li>确定系统内模块之间的关系。确定模块之间的依赖关系及模块的宏观输入和输出。</li>
<li>确定指导后续设计与烟花的原则。使后续的子系统或模块设计在规定的框架内继续演化。</li>
<li>确定非功能性需求。非功能性需求是指安全性、可用性、可扩展性等。</li>
</ul>
留言