架构师必须知道的架构设计原则


不管你是新手程序员、职场老司机,还是资深架构师,这篇文章对你来说应该都有裨益。虽然仍是假期,但也建议你多花点时间读一读这些真言。
写在前面
如果一个技术已经存在 2 年,比如现在很火的前端技术 react 和 vue 等,那么我能预估这个技术大致还有 2 年的生命期,再久就不确定了;如果一个架构或设计原则已经存在 15 年,例如单一职责和依赖倒置原则,我可以预期它还有 15 年甚至更久的生命期。原则是比具体技术更抽象,更接近事物本质,也更经得起时间考验的东西。这些原则沉淀在架构师的脑海中,最终内化成他的 mindset,以潜意识方式影响和指导他的架构和设计工作。
一晃我在软件研发行业工作十多个年头了,前面大部分时间做架构设计和开发,现在转型做研发管理。随着时间的推移,很多技战术细节性的东西 (工具,框架,编程语言) 在我脑海中渐渐模糊,但是一些平时学习积累起来,并且在实践中加深体会的软件架构设计和组织原则,这些原则性的东西却丝毫没有被时间冲淡,反而愈加清新。现在即使我不在一线开发,但这些沉淀下来的原则仍然潜移默化地影响我的日常管理和部分架构设计指导工作。我想有必要总结一下那些业界知名,给我留下深刻印象的软件架构设计和组织原则,和大家一起分享。
软件设计原则
GRASP 通用职责分配软件模式
来自 Craig Larman 的软件设计书《UML 和模式应用》[附录 1],Larman 在书中提出软件设计的关键任务是职责分配,并提炼总结出 9 种 (5 种核心 +4 种扩展) 软件职责分配模式,这些模式是比 GoF 设计模式更抽象的元模式。
1. 信息专家 (Information Expert)
为对象分配职责的通用原则 – 把职责分配给拥有足够信息可以履行职责的专家
2. 创建者 (Creator)
将创建 A 的职责赋给 B,如果至少下面一种情况为真:
  • B“包含”或者聚合 A
  • B 记录 A 的实例
  • B 密切地使用 A
  • B 拥有 A 的初始化数据
    3. 低耦合 (Low Coupling)
    赋予职责使得对象间的耦合度尽可能低,最小化对象间的依赖和变更影响,最大化重用。
    4. 高内聚 (High Cohesion)
    赋予职责使得每个对象的职责尽可能保持聚焦和单一,易于管理和理解。
    5. 控制器 (Controller)
    把职责赋予系统、设备或者子系统的表示类 (门面控制器),或者某个用例的表示类 (用例控制器),让控制器接收事件并协调整个系统的运作。
    6. 多态 (Polymorphism)
    将职责分配给多个具有同名方法的多态子类,运行时根据需要动态切换子类,让系统行为变得可插拔。
    7. 纯虚构 (Pure Fabrication)
    针对真实问题域中不存在,但是设计建模中有用的概念,设计虚构类并赋予职责。
    8. 间接 (Indirection)
    在两个或者多个对象间有交互的情况下,为避免直接耦合,提高重用性,创建中间类并赋予职责,对象的交互交由中间类协调。
    9. 受保护的变化 (Protected Variation)
    简单讲就是封装变化。识别系统中可能的不稳定或者变化,在不稳定组件上创建稳定的抽象接口,将可能的变化封装在接口之后,使得系统内部的不稳定或者变化不会对系统的其它部分产生不良影响。
    SOLID 面向对象设计原则
    S.O.L.I.D 是面向对象设计和编程 (OOD&OOP) 中几个重要原则的首字母缩写,受 Robert Martin 推崇。
    1. 单一职责原则 (The Single Responsibility Principle)
    修改某个类的理由应该只有一个,如果超过一个,说明类承担不止一个职责,要视情况拆分。
![](http://note.youdao.com/yws/public/resource/2bd9df297d760eb861304d63a59d94e4/xmlnote/E164B18101464A4F969C9629937F52A2/2480)
2. 开放封闭原则 (The Open Closed Principle)
软件实体应该对扩展开放,对修改封闭。一般不要直接修改类库源码(即使你有源代码),通过继承等方式扩展。
![](http://note.youdao.com/yws/public/resource/2bd9df297d760eb861304d63a59d94e4/xmlnote/14CA4061A37744DB864BB0AE064E13D0/2483)
3. 里氏替代原则 (The Liskov Substitution Principle)
当一个子类的实例能够被替换成任何超类的实例时,它们之间才是真正的 is-a 关系。
![](http://note.youdao.com/yws/public/resource/2bd9df297d760eb861304d63a59d94e4/xmlnote/46A909D248D042758244123824E4633F/2485)
4. 依赖倒置原则 (The Dependency Inversion Principle)
高层模块不应该依赖于底层模块,二者都应该依赖于抽象。换句话说,依赖于抽象,不要依赖于具体实现。比方说,你不会把电器电源线焊死在室内电源接口处,而是用标准的插头插在标准的插座 (抽象) 上。
![](http://note.youdao.com/yws/public/resource/2bd9df297d760eb861304d63a59d94e4/xmlnote/87E1DE11C3C942E4B5857B13ACE993AF/2481)
5. 接口分离原则 (The Interface Segregation Principle)
不要强迫用户去依赖它们不使用的接口。换句话说,使用多个专门的接口比使用单一的大而全接口要好。
![](http://note.youdao.com/yws/public/resource/2bd9df297d760eb861304d63a59d94e4/xmlnote/1E41A4692C4A429C89406259647F2613/2482)
我的解读
  1. 我职业早年主要关注软件设计和编程,所以花蛮多时间学习和消化 GRASP 和 SOLID 设计原则。这些原则对我影响很深,尤其是单一职责,信息专家,关注分离,依赖倒置 / 封装变化,分而治之等核心原则,现在日常研发中我时常用这些原则指导新手工程师。

  2. 高内聚 + 低耦合,就像道中的一阴一阳,是所有其它 OO 设计原则的原则 (元原则),其它设计原则都是在这两个基础上泛化衍生出来的。

  3. 上述原则虽然是针对 OO 设计和编程提出,但是对于大规模系统架构仍然适用。比如,微服务架构就体现了:

  4. 作为架构师或者设计师,有两个设计能力是需要重点培养的,也是最难和最能体现架构设计水平的:

分布式系统架构设计原则和理论
AKF 架构原则
这 15 个架构原则来自《架构即未来 (The Art of Scalability)》[附录 2] 一书,作者马丁 L. 阿伯特和迈克尔 T. 费舍尔分别是 eBay 和 PayPal 的前 CTO,他们经历过 eBay 和 PayPal 大规模分布式电商平台的架构演进,在一线实战经验的基础上总结并提炼出 15 条架构原则:
1.N + 1 设计
永远不要少于两个,通常为三个。比方说无状态的 Web/API 一般部署至少>=2 个。
2. 回滚设计
确保系统可以回滚到以前发布过的任何版本。可以通过发布系统保留历史版本,或者代码中引入动态开关切换机制 (Feature Switch)。
3. 禁用设计
能够关闭任何发布的功能。新功能隐藏在动态开关机制 (Feature Switch) 后面,可以按需一键打开,如发现问题随时关闭禁用。
4. 监控设计
在设计阶段就必须考虑监控,而不是在实施完毕之后补充。例如在需求阶段就要考虑关键指标监控项,这就是度量驱动开发 (Metrics Driven Development) 的理念。
5. 设计多活数据中心
不要被一个数据中心的解决方案把自己限制住。当然也要考虑成本和公司规模发展阶段。
6. 使用成熟的技术
只用确实好用的技术。商业组织毕竟不是研究机构,技术要落地实用,成熟的技术一般坑都被踩平了,新技术在完全成熟前一般需要踩坑躺坑。
7. 异步设计
能异步尽量用异步,只有当绝对必要或者无法异步时,才使用同步调用。
8. 无状态系统
尽可能无状态,只有当业务确实需要,才使用状态。无状态系统易于扩展,有状态系统不易扩展且状态复杂时更易出错。
9. 水平扩展而非垂直升级
永远不要依赖更大、更快的系统。一般公司成长到一定阶段普遍经历过买更大、更快系统的阶段,即使淘宝当年也买小型机扛流量,后来扛不住才体会这样做不 scalable,所以才有后来的去 IOE 行动。
10. 设计时至少要有两步前瞻性
在扩展性问题发生前考虑好下一步的行动计划。架构师的价值就体现在这里,架构设计对于流量的增长要有提前量。
11. 非核心则购买
如果不是你最擅长,也提供不了差异化的竞争优势则直接购买。避免 Not Invented Here 症状,避免凡事都要重造轮子,毕竟达成业务目标才是重点。
12. 使用商品化硬件
在大多数情况下,便宜的就是最好的。这点和第 9 点是一致的,通过商品化硬件水平扩展,而不是买更大、更快的系统。
13. 小构建、小发布和快试错
全部研发要小构建,不断迭代,让系统不断成长。这个和微服务理念一致。
14. 隔离故障
实现故障隔离设计,通过断路保护避免故障传播和交叉影响。通过舱壁泳道等机制隔离失败单元 (Failure Unit),一个单元的失败不至影响其它单元的正常工作。
15. 自动化
设计和构建自动化的过程。如果机器可以做,就不要依赖于人。自动化是 DevOps 的基础。
我的解读
  1. 这 15 条架构原则基本上是 eBay 在发展,经历过流量数量级增长冲击过程中,通过不断踩坑踩出来的,是干货中的干货。消化吸收这 15 条原则,基本可保系统架构不会有原则性问题。
  2. 这 15 条原则同样适用于现在的微服务架构。eBay 发展较早,它内部其实很早 (差不多 2010 年前) 就已形成完善的微服务生态,只是没有提出微服务这个概念。
  3. 这 15 条原则可根据 TTM(Time To Market),可用性 / 可扩展性 / 质量,成本 / 效率分布在三个环内,如下图所示。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM