什么是好的设计?
我特别喜欢看房屋改造的节目, 很佩服设计师把普通的有缺陷的房屋, 改造的井井有条. 这常常让我想到设计系统, 无论是直接面向客户, 还是内部系统. 系统设计和房屋改造应该有很多
相通的地方可以借鉴.
-
首先就是功能划分很清晰并且合理.
重构, 去除不合理的东西,引入合理的东西,加强薄弱的地方 -
合理并且充分的利用资源, 空间
-
可扩展, 外部需求是一直在变化的, 没有一套固定的架构可以解决所有问题, 好的架构应该有生长能力,即可以动态调整,以适应新的需求,当然通常这类需求遵循一定的规律
比如一个书包, 设计成可以根据人的身高, 调节背带长短, 这样小朋友长高以后还是可以背
比如书桌的高度, 储物间中的隔断可以自由拆卸和组装, 餐桌可以调节和扩缩,等等 -
考虑将来的需求
可扩展就是考虑将来的一方面. -
在设计前, 应该提供多套方案, 收集反馈和权衡利弊后, 再实施
-
设计方案需要考虑 - 该方案造成的影响
首先, 对人的影响, 包括对用户体验的影响, 对devops, 运维,测试,开发同学,合作方的影响
其次, 对业务的影响, 性能是否有影响, 是否会暴露安全隐患
再次, 考虑成本,时间,金钱,人力,物力 -
变化封装
封装的目的之一是把多个可变动的点能够集中到少数或者单个点上去, 通过封装, 原先二层的结构变成了三层, 上层和封装层之间逻辑变得简单, 下层负责封装变化并转换为中间层. 每当下层变化时, 下层负责转换变动到中间层,
使得变化不会传递到上层, 这也就是解耦合.
例如: 有一个retry的类, 封装了retry的逻辑. retry类会接受一个client 接口作为成员变量. 实际执行逻辑时调用client的具体实现类. 由于不同的client会抛出不同的异常, 如果交给retry统一处理, 那么每新增一个client类时, 就需要
改动retry类的异常处理函数. 相反,如果在每个client的具体实现中把各种异常封装转换为 一个公共的类, 那么retry类就只需要关心这个异常类. 将来client中抛异常逻辑变动时,我们就不需要修改retry类中的逻辑了. -
接口用于描述行为, 抽象类用于描述状态. 就类似 程序=算法 + 数据结构 or 程序=控制逻辑 + 业务逻辑. 行为和状态是我们需要设计类时重点考虑的点.