写在前边:本文是自己的学习笔记。可能未必适合所有人学习,不喜勿喷。有错误希望大家能够指出。
单一职责原则
原则分析:
1)一个类承担的职责越多,它被复用的可能性越小,而且如果一个类承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运作。
2)类的职责主要包括两个方面:数据职责和行为职责,数据职责通过其属性来体现,而行为职责通过其方法来体现。
3)单一职责原则是实现高内聚、低耦合的指导方针。
单一职责原则的优点:
1)降低类的复杂性,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
2)提高类的可读性
3)提高代码的可维护性和复用性
4)降低因变更引起的风险,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。
怎样做才算遵循单一指责原则:
不管对于一个类还是一个方法,尽可能的做到“少管闲事”,一个人做一件事就可以了。这样做可以带来的好处还有:我们在有修改的需求的时候,想要修改一个类也好,还是修改一个函数也好,都能不那么头疼,都能少思考一点。
里氏替换原则
定义:
所有引用基类的地方必须能透明的使用其子类对象。
所有引用基类(父类)的地方必须能透明地使用其子类的对象。即子类能够必须能够替换基类能够从出现的地方。子类也能在基类 的基础上新增行为。
最后再用白话讲一下:爸爸做的事都能交给儿子来完成,不管是谁做效果都是一样的。
原则分析:
1)讲的是基类和子类的关系,只有这种关系存在时,里氏代换原则才存在。
2)里氏代换原则可以通俗表述为:在软件中如果能够使用基类对象,那么一定能够使用其子类对象。
3)里氏代换原则是实现开闭原则的重要方式之一。
•继承的优点
•代码共享,减少类数量,每个子类都拥有父类的方法和属性
•提高代码的可重用性
•提高代码的可扩展性
•提高产品或项目的开放性
•继承的缺点
•继承是入侵式的。只要继承,就必须拥有父类的所有属性和方法
•降低代码的灵活性。子类必须拥有父类的属性和方法,受到限制
•增强了耦合性。当父类修改时,必须考虑子类的修改,这种修改可能造成大片的代码需要重构
• 里氏替换原则为良好的继承定义了规范,包含4层含义:
p 子类必须完全实现父类的方法;
p 子类可以有自己的个性;
p 覆盖或实现父类的方法时输入参数可以被放大;
p 覆盖或实现父类的方法时输出结果可以被缩小。
依赖倒置原则
先谈我的理解:本来我们觉得类之间的关系,都因该是直接调用。然而这样做并不好,因为我们想要修改是比较吃力的。所以前人想到通过使用接口的形式,来降低耦合度。使用依赖倒置原则避免了牵一发而动全身的麻烦。
依赖倒置原则的核心就是要我们面向接口编程,理解了面向接口编程,也就理解了依赖倒置。
•包括三层含义 :
p高层模块不应该依赖底层模块,两者都依赖其抽象
p抽象不依赖细节
p细节应该依赖于抽象
原则分析:
1)如果说开闭原则是面向对象设计的目标,依赖倒置原则是到达面向设计“开闭”原则的手段。如果要达到最好的“开闭”原则,就要尽量的遵守依赖倒置原则。
2)依赖倒置原则的常用实现方式之一是在代码中使用抽象类,而将具体类放在配置文件中。
3)类之间的耦合:零耦合关系,具体耦合关系,抽象耦合关系。依赖倒置原则要求客户端依赖于抽象耦合,以抽象方式耦合是依赖倒置原则的关键。
在Java语言中,抽象就是指接口或抽象类,两者都是不能直接被实例化的;细节就是具体的实现类,实现类实现了接口或继承了抽象类,其特点是可以直接被实例化
依赖倒置原则在Java中的体现:
•模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生
•接口或抽象类不依赖于实现类
•实现类依赖于接口或抽象类
依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读性和可维护性
接口隔离原则
还是先谈我的感受:接口隔离原则和单一职责原则有点相近的意味,干的事目的相近。比方说,一个接口中有比较多的方法,那么就有可能有许多的类都想要实现这个接口。高耦合是我们不想看到的,所以我们就要把它撕碎,做法就是将接口尽可能的拆分,拆分尽可能的合理。
•接口
p实例接口:是对一个类型的实物所具有的方法特征的描述。包含了一系列不被实现的方法,而把这些方法的实现交给继承它的类。
p类接口:是指在Java中使用interface严格定义的接口。
•
•接口隔离原则有如下两种定义:
p客户端不应该依赖它不需要的接口;
p类间的依赖关系应该建立在最小的接口上
•接口隔离原则的具体的含义如下 :
p一个类对另外一个类的依赖性应当是建立在最小的接口上的
p一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染。因此使用多个专门的接口比使用单一的总接口要好
p不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。即不要强迫客户使用它们不用的方法,否则这些客户就会面临由于这些不使用的方法的改变所带来的改变
接口隔离原则与单一职责原则的对比
其一,单一职责原则注重的是职责;而接口隔离原则注重对接口依赖的隔离。
其二,单一职责原则主要是约束类,其次才是接口和方法,它针对的是程序中的实现和细节;而接口隔离原则主要约束接口,主要针对抽象,针对程序整体框架的构建.。
迪米特法则
一个对象应当对其他对象尽可能少的了解。知道的越少,牵连就越少,修改起来就越容易。这样做达到高内聚的目的。
迪米特法则的核心观念就是类之间的解耦、弱耦合,只有弱耦合了以后,类的复用率才可以提高
•迪米特法则具有代表性的表述 :
p只与你直接的朋友们通信
p不要跟“陌生人”说话
p每一个软件单位对其他的单位都只有最少的了解,这些了解仅局限于那些与本单位密切相关的软件单位
问题由来:
类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。
解决方案:
尽量降低类与类之间的耦合。
法则分析:
1)朋友类:
在迪米特法则中,对于一个对象,其朋友包括以下几类:
(1) 当前对象本身(this);
(2) 以参数形式传入到当前对象方法中的对象;
(3) 当前对象的成员对象;
(4) 如果当前对象的成员对象是一个集合,那么集合中的元素也都是朋友;
(5) 当前对象所创建的对象。
任何一个对象,如果满足上面的条件之一,就是当前对象的“朋友”,否则就是“陌生人”。
迪米特法则的主要用途:在于控制信息的过载。
•在类的划分上,应当尽量创建松耦合的类,类之间的耦合度越低,就越有利于复用,一个处在松耦合中的类一旦被修改,不会对关联的类造成太大波及;
•在类的结构设计上,每一个类都应当尽量降低其成员变量和成员函数的访问权限;
•在类的设计上,只要有可能,一个类型应当设计成不变类;
•在对其他类的引用上,一个对象对其他对象的引用应当降到最低。
开闭原则
一个软件实体应当对扩展开放,对修改关闭。
为什么这样做呢:对软件的修改是关闭的,因为想要修改原来的代码。在不清楚代码逻辑的情况下,很容易出现很多的问题。为了安全考虑,对代码的修改是关闭的。但是系统不可能是一成不变的,功能肯定是要增加的,所以说扩展开放的。
开闭原则的作用
p提高复用性
p提高可维护性
p提高灵活性
p易于测试
原则分析 :
1)当软件实体因需求要变化时, 尽量通过扩展已有软件实体,可以提供新的行为,以满足对软件的新的需求,而不是修改已有的代码,使变化中的软件有一定的适应性和灵活性。
2)实现开闭原则的关键就是抽象化。
3)可变性的封闭原则:找到系统的可变因素,将它封装起来. 这是对“开-闭”原则最好的实现。
开闭原则的应用:
需求变更:
按照9折销售图书 遵照“开闭原则”中对修改关闭的原则,不能直接修改IBook接口和NovelBook类,而是通过增加一个子类OffNovelBook来完成
原则总结:
开闭原则是面向对象设计中最基础的设计原则,它指导我们如何建立稳定灵活的系统。1
只要我们对前面5项原则遵守的好了,设计出的软件自然是符合开闭原则的
开闭原则无非就是想表达:用抽象构建框架,用实现扩展细节。
再回想一下前面说的5项原则,恰恰是告诉我们用抽象构建框架,用实现扩展细节的注意事项而已:
- 单一职责原则告诉我们实现类要职责单一;
- 里氏替换原则告诉我们不要破坏继承体系;
- 依赖倒置原则告诉我们要面向接口编程;
- 接口隔离原则告诉我们在设计接口的时候要精简单一;
- 迪米特法则告诉我们要降低耦合。
而开闭原则是总纲,他告诉我们要对扩展开放,对修改关闭。