设计模式学习笔记(一)

来源:互联网 发布:spring编程步骤 编辑:程序博客网 时间:2024/05/18 16:58

设计模式学习笔记(一)


六大原则

1.单一职责原则(SRP)

应该有且仅有一个原因引起类的变更

通俗地讲,就是每个类只负责一项职责。(增强内聚)
解决的问题:如果一个类有一个以上的职责,这些职责就耦合在了一起,导致重构代码时,“牵一发而动全身”,使代码维护变得困难(所以要松耦合)。
另外,它还能减少职责扩散带来的代码维护困难的问题

职责扩散:因为某种原因,某一职责被分化为颗粒度更细的多个职责。

但职责扩散是没法避免的,在实际应用中,类的单一职责还要根据项目实际需求来考虑,而接口一定要做到单一职责,最好用接口组合的方式来实现单一职责。

2.里氏替换原则(LSP)

所有引用基类的地方必须能透明地使用其子类

通俗地讲,就是父类出现的地方子类就一定能出现,子类出现的地方父类未必能出现。
它又有着四层含义:
I.子类必须实现(覆写)父类的抽象方法,但不实现父类的非抽象方法。

  • 如果子类实现了父类的非抽象方法,可能会改变父类方法原本的功能。

II.子类可以扩展(定义)自己的方法。
III.子类重载(注意不是覆写)父类方法时,方法的入口参数的范围可以比父类大。

  • 如果子类入口参数比父类小,会让子类方法得不到调用,也就是说抹掉了子类的“个性”。

IV.子类重载父类方法时出口参数(返回值)可以被缩小。

LSP的目的是:解决继承关系中存在的问题,以及实现真正的多态。 其中第三、四层含义,保证了父类替换成子类时,子类方法能被正确调用。

LSP是继承复用的基石,只有当子类可以替换基类,软件单位的功能不受影响时,基类才能真正的被复用,而子类也可以在基类的基础上增加新的行为,里氏替换原则是实现开放封闭原则的具体规范。

LSP的目的就是增加程序的健壮性,需求变更时也可以保持良好的兼容性和稳定性,即使增加子类,原有的子类可以继续运行。

3.依赖倒置原则(DIP)

I.高层模块不应该依赖低层模块,两者都要依赖其抽象
II.抽象不应该依赖细节
III.细节不应该依赖抽象

Java中,细节可以理解为实现类(模块),抽象可以理解为抽象类或者接口。
而依赖倒置的作用是降低类之间的耦合
依赖的三种写法:(依赖注入的方式)
a.通过构造函数传递(注入)依赖对象。
b.通过setter方法传递依赖对象。
c.通过接口传递依赖对象。

实际项目中应用:
a.每个尽量子类都要有接口或抽象类。
b.变量的表面尽量是接口或抽象类。
c.任何类都不该从具体类派生。
d.尽量不覆写基类方法(开闭原则)
e.结合里氏替换原则使用

4.接口隔离原则(ISP):

I.客户端不依赖它不需要的接口
II.类间的依赖关系应建立在最小接口上

通俗解释:I.接口功能尽量单一。II.接口尽量细化。

使用原因:分散定义接口,可预防未来变更,提高项目灵活性与稳定性。
注意:a.根据接口分离原则拆分接口,必须满足单一职责原则。b.应根据实际需求来设计接口和决定接口划分的粒度。

5.迪米特法则(LoD)(最小知识原则)

一个对象应该对其他对象有最少了解

即一个类应该对自己需要耦合或调用的类了解最少。
含义:
1.朋友类:出现在类的成员变量,方法的输入输出参数中的类,但出现在方法体内部的类不属于朋友类。
一个类只与朋友进行交流。要是与陌生类交流,则会提升耦合度,即一个方法体内部尽量不引入类中不存在的对象(JDK除外)
2.朋友间距离:一个类不要暴露过多的方法给朋友类。
可以把多个私有方法封装到一个公有方法中,以降低耦合。(这一点在JDK源码中经常见到)
3.如果一个方法放在本类中,既不增加类间关系,也不对本类产生影响,就放在本类中。
4.应该谨慎使用Serializable接口

LoD的这些要求的结果就是产生了大量的中转方法和跳转类,给维护带来难度。
在实际应用当中,如果一个类跳转两次以上才能访问到另一个类,那就需要想办法进行重构了。

6.开闭原则(OCP)(开放封闭原则)

一个软件实体,如类、模块和函数应该对扩展开放,对修改关闭。

含义:一个软件实体应该通过扩展已有的类来应对新出现的变化,而不是通过修改类来实现变化。

开闭原则是可复用设计的基石,提高了可复用性,减少了未来的改动。
开闭原则的一个具体体现是里氏替换原则,其它设计原则也都是实现开闭原则的一种手段。

7.总结

这几种原则中,开闭原则是作为基础存在的,而其他的原则之间也是可以有相互联系的,考虑到实际需求,有时候是可以违背这些设计原则的,但要注意一下这样做可能为实际项目带来的后果。

原创粉丝点击