《设计模式》-02-面向对象的设计原则(单一职责,开放、闭合原则,接口隔离原则,依赖倒置原则,liskov替换原则,代码缺陷)
文章目录
1. 单一职责
1.1 概述
单一职责原则强调一个类或模块应仅有一个引起其变化的因素(职责)
诠释:
通俗地讲,一个类或模块应只承担一个(或一种类型的)业务职责,而不是将内聚度较弱的业务行为强行耦合。
因为,当类承担的业务职责较多时,该类中任何职责需求的变化都会引起静态实现的变化,导致其代码不稳定。
- 示例
如将订单系统和用户系统分开等等
1.2 不良影响
- 设计类数量的增加
如果一个庞大的业务系统的所有类都按单一职责设计,则有可能导致设计类数量的“爆炸(Explosion)”。此外,设计类数量的增加也会使设计方案的复杂度增大。 - 破坏类的封装特性
由于数据域封装在目标(实体)类中,如果从目标类中将含有数据域访问逻辑的业务行为分离出去,则势必造成外部代码访问目标类私有域的问题,而最终破坏目标类的封装特性。
2. 开放、闭合原则
2.1 概述
开放/闭合原则:要求类或模块的代码“对扩展是开放的(Open for Extension),对修改是关闭的”(Close for Modification)。
诠释:
这意味着,当软件需求发生变化时,目标类或模块的代码可以通过代码扩展很容易地实现新的需求,而不是修改已有类。
- 示例:
一个支付类 将某宝支付
和某信支付
分为两个子类,加入信用卡支付
或修改某信支付
时并不需全盘修改。
2.1 不良影响
-
代码可读性降低
抽象代码层隐藏了具体的业务细节,大大降低了代码的可读性。 -
程序测试成本增加
3. 接口隔离原则
3.1 概述
如果某个接口的行为不是内聚的,就应该按照业务分组,并将分组后的业务行为通过隔离的接口单独定义。
3.2 不良影响
- 接口数量“爆炸”
- 代码抽象度高
抽象度高的代码具有稳定性、可复用性等优点,面向抽象编程较为推崇这种代码设计思维。但也应指出,代码抽象度越高,代码实现越复杂;代码抽象度越高,代码可读性(或可理解度)越差。
4. 依赖倒置原则
4.1 概述
高层模块不应依赖于低层模块,二者都应该依赖于抽象;抽象不应依赖于细节,细节应依赖于抽象。
4.2 不良影响
增加了代码的复杂度。
5. liskov替换原则
5.1 概述
建议子类对象必须能够完全替换掉它们的父类对象,而不需要改变父类的任何属性。
5.2 违反liskov原则
5.2.1 违反的示例
- 如下图,画一个表格,有柱状图和线图两种,柱状图需要画图和填充,而折线图只需要绘图
说明:
客户端ChartDrawer类
在绘制不同类型图表组件时,需要知道父类ChartComponent
的子类,然后才能对该组件进行绘制操作,这违反了Liskov替换原则。
因为Liskov替换原则建议:对于客户端程序ChartDrawer来说drawChart()绘制行为使用的父类ChartComponent定义的对象,是可以被其子类Bar或Line定义的对象完全替换,而不需要提供额外的子类信息。
- 解决
使得绘图包含填充,则子类可替换父类而不需要输入额外的子类信息。
5.2.2 违反后的代码缺陷
- 可扩展性差
- 容易引入逻辑错误
5.3 不良影响
- 在继承关系中,父类与子类之间是强约束关联
即子类只能实现(或继承)父类的定义(域或行为),而不能更改;父类定义(域或行为)的变化会迫使所有子类随之变化。 - 限制了子类重写父类行为的逻辑,降低了代码的灵活性