Loading

设计模式七大原则

一、单一职责原则(SRP)

定义:单一职责原则(Single Responsibility Principle)

指一个类或者模块应该有且只有一个改变的原因。
如果一个类承担的职责过多,就等于把这些职责耦合在一起了。一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。
这种耦合会导致脆弱的设计,当发生改变时,设计就会遭到意想不到的破坏。
而如果想要避免这种现象的发生,就要尽可能的遵守单一职责原则。
此原则的核心就是解耦和增强内聚性。

怎么做:

降低类的复杂度,一个类只负责一项职责
提高类的可读性,可维护性
降低变更引起的风险

人话:
比如有一个我们有一个Aniaml类,其中有一个run的方法,给Aniaml一个属性animalName来分辨动物。
然后调用一个run()方法来形容动物的运动代码就是这样
System . out .println( animalName + " 在地上奔跑 ..." ) ; ,
当我们用不同动物运行run()方法的时候神奇的事情就发生了,
如果animalName是老鼠、猫时,老鼠/猫 在地上奔跑,看起来没什么问题;
如果animalName是麻雀、老鹰时,麻雀/老鹰 在地上奔跑,emm,虽然看起来有点怪,但是他们也有腿;
如果animalName是金鱼、鲨鱼时,金鱼/鲨鱼 在地上奔跑,what?它们有腿吗???

解决方案在上面就说过了,降低类的复杂度,我们可以将动物类拆成天上飞的动物、水里游的动物、地上跑的动物
这样就不会出现上面的这种情况了。

这些原则解释起来都很麻烦,需要自己理解其中的“奥妙”,如果看不懂说明还不到看的时候,over。

通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单,才可以在代码级别违反单一职责原则,只有类中方法数量足够多,才可以在方法级别保持单一职责原则

二、接口隔离原则(ISP)

定义:接口隔离原则(Interface Segregation Principle)

客户端不应该依赖他不需要的的接口
类之间的依赖关系应该建立在最小接口上
使用接口隔离原则的前提是需要满足单一职责原则

人话:
比如我们A接口有5个抽象方法,B类需要其中的前3个方法,C类需要后3个方法
我们在写代码时候让B类和C类去实现A接口,那必须把5个抽象方法全部实现,但是明明B就只需要前3个,C只需要后3个,剩余不需要的方法就会变成空方法,不然这个类还得声明称抽象类,这样就很不符合逻辑。
解决这个问题我们只要将A接口拆分,把前两个方法拆成E接口,后3个接口拆分为F接口,第三个接口拆成G接口,类B只需要实现接口E、G,而类C只需要实现接口F、G即可
这样就不会发生不需要但是不得不实现一些类本身不需要的抽象方法,这就叫接口隔离原则。

三、里氏替换原则(LSP)

定义:

所有引用基类的地方必须能透明的使用其子类的对象
任何基类可以出现的地方,子类都可以出现
里氏替换原则是对开闭原则的补充

怎么做:

  • 在使用继承时,子类中尽量不要重写父类的方法
  • 继承实际上会让两个类耦合度增强,可以通过聚合、组合、依赖,来解决该问题

四、依赖倒转原则(DIP)

定义:

高层模块不应该依赖低层模块,二者都应该依赖其抽象
抽象不应该依赖细节,细节应该依赖抽象
依赖倒转的中心思想是面向接口编程

这里需要解释一下依赖传递的三种方式,分别是

  1. 接口传递
  2. 构造方法传递
  3. set传递

怎么做:

  • 低层模块尽量都要有抽象类或接口,或者二者都有,程序稳定性会更好
  • 变量的声明类型尽量是抽象类或接口,这样我们的变量引用和实际对象之间,就存在一个缓冲层,有利于对程序的扩展和优化
  • 继承时遵循里氏替换原则

五、开闭原则(OCP)

定义:

一个软件实体类、模块、函数应该对扩展开放,对修改关闭
模块应该在尽量不修改原来代码的情况下进行扩展
在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化

怎么做:

  • 通过接口或抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法,也就是扩展时必须添加具体实现而不是改变具体的方法
  • 参数类型、引用对象尽量使用接口或者抽象类,而不是实现类,这样就能尽量保证抽象层是稳定的
  • 一般抽象模块设计完成后,不再允许修改接口或抽象方法的定义

六、迪米特原则(LOD)

定义:

一个对象应该对其他对象保持最少的了解
类与类之间的关系越密切,耦合度就越大
迪米特法则,也叫最少知道原则,即一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的public方法,不对外泄露任何信息
只与直接的朋友通信

总结:

  • 迪米特法则的核心是降低类之间的耦合
  • 由于每个类之间都减少了不必要的依赖,因此迪米特法则只是要求降低对象之间的耦合关系,并不是要求完全没有依赖关系

七、合成复用原则(CARP)

定义:

尽量使用合成或者聚合的方式,而不是使用继承
在一个新的对象中使用一些已有的对象,使之成为新对象的一部分。新的对象通过向内部持有的这些对象的委派达到复用已有功能的目的,而不是通过继承来获得已有的功能。

什么是聚合:

聚合表示一种弱的“拥有”关系,一般表现为松散的整体和部分的关系,其实所谓的整体和部分也可以是完全不相关的

什么是合成:

合成表示一种强的“拥有”关系,一般表现为严格的整体和部分的关系,部分和整体的生命周期是一样的

posted @ 2022-06-21 19:38  仲景  阅读(57)  评论(0)    收藏  举报