Design Pattern

设计模式七大原则

2023-01-02  本文已影响0人  面向对象架构

总原则:开闭原则(Open Close Principle)

对扩展开放,对修改关闭(可复用设计,抽象化)

在程序需要进行扩展的时候,不能去修改原有的代码,而是要扩展原有代码,实现一个热插拔的效果。

一句话概括:为了使程序的扩展性好,易于维护和升级。

xml和properties等格式的配置文件是纯文本文件,无须编译,因此在软件开发中,一般不把对配置文件的修改认为是对系统源代码的修改(符合开闭原则)。

1. 单一职责原则(SRP,Single Responsibility Principle)

高内聚、低耦合

2、里氏替换原则(LSP,Liskov Substitution Principle)

所有引用基类(父类)的地方必须能透明地使用其子类的对象。

里氏替换原则中,子类对父类的方法尽量不要重写和重载。因为父类代表了定义好的结构,通过这个规范的接口与外界交互,子类不应该随便破快它。

在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。

注意点:

3、依赖倒转原则(DIP,Dependence Inversion Principle)

抽象不应该依赖于细节,细节应当依赖于抽象。即,要针对接口编程,而不是针对实现编程。

DIP是开闭原则的基础,具体内容:面向接口编程,依赖于抽象而不依赖于具体。写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互。

依赖倒转原则要求我们在程序代码中传递参数时或在关联关系中,尽量引用层次高的抽象层类,即使用接口和抽象类进行变量类型声明、参数类型声明、方法返回类型声明,以及数据类型的转换等,而不要用具体类来做这些事情。为了确保该原则的应用,一个具体类应当只实现接口或抽象类中声明过的方法,而不要给出多余的方法,否则将无法调用到在子类中增加的新方法。

在引入抽象层后,系统将具有很好的灵活性,在程序中尽量使用抽象层进行编程,而将具体类写在配置文件中,这样一来,如果系统行为发生变化,只需要对抽象层进行扩展,并修改配置文件,而无须修改原有系统的源代码,在不修改的情况下来扩展系统的功能,满足开闭原则的要求。

在实现依赖倒转原则时,我们需要针对抽象层编程,而将具体类的对象通过依赖注入(DependencyInjection,DI)的方式注入到其他对象中,依赖注入是指当一个对象要与其他对象发生依赖关系时,通过抽象来注入所依赖的对象。常用的注入方式有三种,分别是:构造注入,设值注入(Setter注入)和接口注入。构造注入是指通过构造函数来传入具体类的对象,设值注入是指通过Setter方法来传入具体类的对象,而接口注入是指通过在接口中声明的业务方法来传入具体类的对象。这些方法在定义时使用的是抽象类型,在运行时再传入具体类型的对象,由子类对象来覆盖父类对象。

开闭原则是目标,里氏替换原则是基础,依赖倒转原则是手段。

4、接口隔离原则(ISP,Interface Segregation Principle)

使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。

每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个接口)要好。

在使用接口隔离原则时,需要注意控制接口的粒度,接口不能太小,如果太小会导致系统中接口泛滥,不利于维护;接口也不能太大,太大的即可将违背接口隔离原则,灵活性较差,使用起来很不方便。

5、迪米特法则(LOD,Law of Demeter,最少直到原则)

一个软件实体应当尽可能少地与其他实体发生相互作用(保持松散的耦合关系)。

一个类对自己依赖的类知道的越少越好。无论被依赖的类多么复杂,都应该将逻辑封装在方法的内部,通过public方法提供给外部。这样当被依赖的类变化时,才能最小的影响该类。

迪米特法则(另一种形式:不要和“陌生人”说话,只与你的直接朋友通信)中,对于一个对象,其朋友包括以下几类:

  1. 当前对象本身(this);
  2. 以参数形式传入到当前对象方法中的对象;
  3. 当前对象的成员对象;
  4. 如果当前对象的成员对象是一个集合,那么集合中的元素也都是朋友;
  5. 当前对象所创建的对象。

通过引入一个合理的第三者来降低现有对象之间的耦合度:

应该尽量减少对象之间的交互,如果两个对象之间不必彼此直接通信,那么这两个对象就不应当发生任何直接的相互作用,如果其中的一个对象需要调用另一个对象的某一个方法的话,可以通过第三者转发这个调用。

注意:

  1. 在类的划分上,应当尽量创建松耦合的类,类之间的耦合度越低,就越有利于复用,一个处在松耦合中的类一旦被修改,不会对关联的类造成太大波及
  2. 在类的结构设计上,每一个类都应当尽量降低其成员变量和成员函数的访问权限
  3. 在类的设计上,只要有可能,一个类型应当设计成不变类
  4. 在对其他类的引用上,一个对象对其他对象的引用应当降到最低

6、合成/聚合复用原则(CRP,Composite Reuse Principle)

'尽量首先使用合成/聚合的方式,而不是使用继承'

  1. 继承复用破坏包装,它把父类的实现细节直接暴露给了子类,这违背了信息隐藏的原则;
  2. 如果父类发生了改变,那么子类也要发生相应的该表,这就直接导致了类与类之间的高耦合,不利于类的扩展、复用、维护等,也带来了系统僵硬和脆弱的设计。

Coad法则
只有当以下Coad条件全部被满足时,才应当使用继承关系:

7、开放-闭合原则(OCP)

开放-关闭原则表示软件实体 (类、模块、函数等等) 应该是可以被扩展的,但是不可被修改。(Open for extension, close for modification)。

如果一个软件能够满足 OCP 原则,那么它将有两项优点:

能够扩展已存在的系统,能够提供新的功能满足新的需求,因此该软件有着很强的适应性和灵活性。
已存在的模块,特别是那些重要的抽象模块,不需要被修改,那么该软件就有很强的稳定性和持久性。

注:
“Is-A”代表一个类是另外一个类的一种;
“Has-A”代表一个类是另外一个类的一个角色,而不是另外一个类的特殊种类。

上一篇下一篇

猜你喜欢

热点阅读