一、面向对象设计原则分类

二、SOLID原则
(一)、单一职责原则
1.定义
一个对象应只包含单一的职责,并且该职责被完美的封装在一个类中
2.示例
1)改进前RoleDataOperation类,承载了“数据库连接”、“数据库数据操作”和“存档数据”三种功能,不符合单一职责原则

2)修改后,将三种职责拆分

(二)、开闭原则
1.定义
软件实体尽量在不修改源码的情况下进行扩展
1)软件实体:一个软件模块、一个由多个类组成的局部结构或一个独立的类
2.示例
1)修改前,刷怪塔creatMonster类在扩展新怪物时需要修改类中的代码

2)修改后,将参数改为Monster类,直接传递对应的“怪物”对象即可

(三)、里氏替换原则
1.定义
所有引用基类(父类)的地方必须能透明地使用其子类的对象
1)在软件中将一个基类替换为它的子类对象,程序不会产生任何错误,反之则不成立
2)实现开闭原则的重要方式:程序中尽量使用基类类型,运行时在确定子类的类型,用子类对象来替换父类对象
2.示例
1)Client类中参数为基类,实际使用中传入子类对象作为参数

(四)、依赖倒置原则
1.定义
高层模块不应该从低层模块导入任何东西,两者都应依赖于抽象。抽象不依赖于细节,细节依赖于抽象。即,针对接口编程,而不是针对实现编程
1)要求程序代码中尽量引用层次搞得抽象层类
2)在针对抽象层编程时,通过“依赖注入”将具体的类注入到其他对象中
3)“依赖注入”主要包含
构造注入:通过构造函数传入具体的类
设值注入(Setter注入):用过Setter方法传入具体类的对象
接口注入:通过在接口中声明业务方法来传入具体类的对象
2.示例
1)DataBiz类属于针对具体实现进行编程,而不是针对抽象
在数据格式变更时需要反复修改其代码

2)增加一层抽象DataConvert类,DataBiz只针对DataConvert类进行编程

(五)、接口隔离原则
1.定义
一套接口应当负责单一的职责,不应含有冗余部分
2.示例
1)Amazon类与Dropbox类都必须实现接口中的五个方法,但实际上Dropbox类不需要不提供其中三个方法

2)改进后将接口细分,每一个接口负责一部分功能

三、组合复用原则
1.定义
优先使用对象的组合,而不是使用继承来达到复用的目的
1)组合/聚合可以使得系统更加灵活,降低类之间的耦合。这样一个类的变化对其他类的影响相对较少
2)基类发生变化时,子类不得不变化。子类继承得来的实现是静态的,无法在运行时变化。所以继承不具有灵活性
“白箱”复用与“黑箱”复用
“白箱”复用:继承会将基类的实现细节暴露给子类。
“黑箱”复用:组合/聚合的对象,其内部细节是不可见的。
2.示例
1)通过不断继承会使得类的数量指数级增长,降低维护性和拓展性

2)应当使用组合/聚合的方式降低类的复杂度

四、迪米特法则
(一)、定义
1.特点
迪米特法则可以降低系统的耦合度,使类与类之间保持松散的耦合关系
2.狭义迪米特法则
1)尽量减少对象之间的交互。
2)若一个对象需要调用另一个对象的某一个方法,可以通过第三者转发这个调用。即,通过引入一个合理的第三者降低现有对象之间的耦合度
3.广义迪米特法则
1)每一个类都应当尽量其成员变量与成员方法的访问权限
2)只要有可能,一个类型应当定义为静态的
3)一个对象对其他对象的引用应当降到最低
(二)、示例
1.只与最直接的对象通信
1)在示例中Teacher类对“非直接对象”Student类进行了通信,违背迪米特法则

2)应当将学生名单存储在Monitor类中,Teacher类只与Monitor类通信

2.减少类对外暴露的方法
1)在示例中WashingMachinge方法对外暴露了所有方法。导致Human类需要进行过多的操作且可能发生错误。

2)通过对WashingMachine进一步封装,只对外暴露worker方法简化实现

