学习设计原则是学习设计模式的基础。千万不能形成强迫症。当碰到业务复杂的场景时,需要随机应变。
在实际开发过程中,并不是一定要求所有代码都遵循设计原则,而是要在适当的场景遵循设计原则,就可以帮助开发者设计出更加优雅的代码结构。
七大原则一句话总结:
一、开闭原则
1、定义
开闭原则(Open-Closed Principle, OCP)
,是指一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
所谓开闭
,也正是对扩展和修改两个行为的一个原则,开闭原则是面向对象设计中最基础的设计原则。
实现开闭原则的核心思想就是面向抽象编程。
2、作用
调用抽象构建框架,用实现扩展细节,可以提高代码的可复用性和软件系统的可维护性。
二、依赖倒置原则
1、定义
依赖倒置原则(Dependence Inversion Principle,DIP)
,是指设计代码结构时,高层模块不应该依赖底层模块,二者都应该依赖其抽象。
抽象不应该依赖细节,细节应该依赖抽象。
2、作用
通过依赖倒置,可以减少类与类之间的耦合性,提高系统的稳定性,提高代码的可读性和可维护性,并降低修改程序所造成的风险。
注意:
以抽象为基准比以细节为基准搭建起来的架构要稳定得多。
三、单一职责原则
1、定义
单一职责(Simple Responsibility Pinciple,SRP)
,是指不要存在一个以上导致类变更的原因。
比如:一个 Class负责两个职责,一旦发生需求变更,修改其中一个职责的逻辑代码,有可能会导致另一个职责的功能发生故障。于是可以给两个职责分别用两个 Class来实现,进行解耦,即使以后需求变更维护也互不影响。
单一职责原则就是一个 Class/Interface/Method只负责一项职责。
在实际开发中,尽可能地让接口和方法保持单一职责,对项目后期的维护是有很大帮助的。
2、作用
单一职责原则的核心就是控制类的粒度大小、将对象解耦、提高其内聚性。
具体来说,其作用如下:
- 降低类的复杂度。
- 提高类的可读性。
- 提高系统的可维护性。
- 变更引起的风险降低。
四、接口隔离原则
1、定义
接口隔离原则(Interface Segregation Principle, ISP)
,是指用多个专门的接口,而不使用单一的总接口,客户端不应该依赖它不需要的接口。
这个原则指导我们在设计接口时,应当注意一下几点:
- 一个类对一类的依赖应该建立在最小的接口之上
- 建立单一接口,不要建立庞大臃肿的接口
- 尽量细化接口,接口中的方法尽量少(不是越少越好,一定要适度)
2、作用
接口隔离原则符合“高内聚,低耦合”的设计思想,使得类具有很好的可读性、可扩展性和可维护性。
五、迪米特法则
1、定义
迪米特原则(Law of Demeter LoD)又称作最少知道原则(Least Knowledge Principle,LKP)
,是指一个对象应该对其他对象保持最少的了解,尽量降低类与类之间的耦合。
迪米特原则主要强调只和朋友交流,不和陌生人说话。
- 朋友的定义:
出现在成员变量、方法的输入和输出参数中的类都可以称之为成员朋友类 - 陌生人的定义:
出现在方法体内部的类不属于朋友类
2、作用
- 提高模块的相对独立性,降低类之间的耦合度。
- 亲合度降低,从而提高了类的可复用率和系统的扩展性。
六、里氏替换原则
1、定义
里氏替换原则(Liskov Substitution Principle,LSP)
,是指一个软件实体如果适用于一个父类,则一定适用于其子类,所有引用父类的地方必须能透明地使用其子类的对象,子类对象能够替换父类对象,而程序逻辑不变。
也可以理解为子类可以扩展父类的功能,但不能改变父类原有的功能。也就是说:子类继承父类时,除了添加新的方法完成新增功能外,尽量不要重写父类的方法。
里氏替换原则只存于父类与子类之间,约束继承泛滥。
2、作用
- 里氏替换原则是实现开闭原则的重要方式之一。
- 它克服了继承中重写父类造成的可复用性变差的缺点。
- 它是动作正确性的保证。即类的扩展不会给已有的系统引入新的错误,降低代码出错的可能性。
- 加强程序的健壮性,同时变更时可以做到非常好的兼容性,提高程序的维护性、可扩展性,降低需求变更时引入的风险。
七、合成复用原则
1、定义
合成复用原则(Composite/Aggregate Reuse Principle,CARP)
,是指尽量使用对象组合(has-a)或聚合(contanis-a)的方式实现代码复用,而不是继承关系达到代码复用的目的。
继承
又称为白箱复用,相当于把所有的实现细节暴露给子类。
组合/聚合
又称为黑箱复用,对类以外的对象是无法获取到实现细节的。
2、作用
- 维持类的封装性
因为成分对象的内部细节是新对象看不见的,所以这种复用又称为“黑箱”复用。 - 新旧类之间的耦合度低
这种复用所需的依赖较少,新对象存取成分对象的唯一方法是通过成分对象的接口。 - 复用的灵活性高
这种复用可以在运行时动态进行,新对象可以动态地引用与成分对象类型相同的对象。
参考文章:
- 软件设计的七大原则:https://www.jianshu.com/p/613d182ffceb
– 求知若饥,虚心若愚。