一、前言
如果一个技术已经存在3年,比如现在很火的前端技术react和vue等,那么我能预估这个技术大致还有3年的生命期,再久就不确定了;如果一个架构或设计原则已经存在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面向对象设计原则
1. 单一职责原则(The Single Responsibility Principle)
修改某个类的理由应该只有一个,如果超过一个,说明类承担不止一个职责,要视情况拆分。
2. 开放封闭原则(The Open Closed Principle)
软件实体应该对扩展开放,对修改封闭。一般不要直接修改类库源码(即使你有源代码),通过继承等方式扩展。
3. 里氏替代原则(The Liskov Substitution Principle)
当一个子类的实例能够被替换成任何超类的实例时,它们之间才是真正的is-a关系。