1.开闭原则OCP(Open-close Principle)
开闭原则:
- 原则应当允许功能拓展(开放性)
- 但不允许修改原有代码(关闭性)
遵循开-闭原则的模块符合以下准则:
- 可以拓展行为已满足新的需求
- 不允许修改程序的源代码
- 在软件开发中,新的功能最好已添加新的类方式去完成,而不影响已有的代码
例:
其中Car和Engine是聚合关系。
当需要增加新的发动机的时候的,只要新的发动机类继承AbstractEngine。Car只需要实现AbstractEngine类即可,
新增加的对Car没影响,这便体现了开-闭原则(和隔离变化实现的效果差不多)。
开闭原则的启示:
- 对象数据:定义为私有
- 不使用全局变量
用组合代替继承
继承
优点:
- 子类实现了父类的全部优点
- 代码实现明确展示
缺点:
- 打破了"封装性",父类与子类的高度耦合
- 代码是静态/编译 的时候绑定的
- 要满足父类的“硬行”规定
- 需要了解整个继承树
对象组合
优点:
- 没有打破封性
- 对象组合是动态/运行 时绑定的
- 整体与部分之间只有接口边界关联(面向接口)
- 各个部分的职责明确(提高重用性、容易独立测试、可阅读性增加)
3.依赖倒置原则DIP( Dependency Inversion Principle)
- 高层模块不应当依赖底层模块,两者都依赖抽象
- 抽象不能依赖细节,细节应当依赖抽象
引导:
- 基类不应该知道任何子类
- 不能依赖一个有详细实现的模块,而这个模块本身也应该依赖抽象
例:
上图, 其中Manager(高层)依赖于Worker(低层)。但是Worker的种类有许多种,Worker的改
动将会影响到Manager,造成不了不稳定。因此,根据依赖倒置原则,Worker应该抽象为一个接口,
不同种类的Worker去实现这个接口。
1.面向接口编程
接口/抽象一般不需要修改
例外:有一些类已经非常成熟稳定了,不用符合这个原则:例如String…
2.避免传递性依赖
4.单一职责原则SRP(Single Responsibility Principle)
-
在软件设计或代码开发中,一个类应该只有一个变化因素。单一职责原则也是高内聚的体现。
一个类只做一件事情,使代码稳定,代码容易维护、易读。
例:
有这样的一个类
其中,Book里面保存者书籍的信息,并提供查看。这样的设计的就不符合单一职责原则。
Book这个类做了两件事:
1.记录书籍的基本信息。
2.提供了看书的方法。
Book类应该只做一件事:保存书籍信息。 此外把看书的行为抽象为一个类:Viewer。对
看书方法有很多,又要适应其中的变化。于是便把Viewer设计为接口。
如下所示:
5.接口隔离原则ISP(Interface Segregation Principle)
软件设计或者代码开发中,客户不应该被强制实现/依赖 它们不需要的接口功能
例:
在此案例中,Worker是一个接口。其中NomalWorker、SpecialWorker、Robot都去实现此接口。
对于NomalWoker和SpecialWorker来说,work方法和eat方法都正常实现。但是对于Robot来说,因
为语言的特性,其中的eat方法的实现显得冗余了,不符合接口隔离原则。其次我们这样设计:
我们把原来的Worker接口,我们分为两个接口:Iworker和Ifeedable。然后其他类只需要去实现
自己需要的接口就可以,同时也避免了冗余。
6.李式替换原则LSP(Liskov’s Substitution Principle)
在软件开发中,子类可以完全替代父类。子类继承父类时,不应该改变父类的行为/功能。
(子类不能修改父类已经实现的方法,子类可以添加新的方法)