【设计模式】设计原则与设计模式

前言

一切设计都为了代码的可扩展性和可读性,都为了应对变化!

我们是基于设计原则的思想,来选择设计模式去实现,代码可读,可扩展的目标!

1 设计原则


1.1 开闭原则(Open-Closed Principle, OCP)

核心设计思想:对扩展开放,对修改关闭。

含义:抽象可变功能,可变功能通过子类扩展实现,避免对已有抽象实现的修改。

优点:便于扩展;

1.2 单一职责(Simple Responsibility Pinciple,SRP)

核心设计思想:单个方法或单个类或单个包,应该包含单一的职责

含义:

  • 一个方法应该只负责一个功能,如果方法的功能包含很多,代码很臃肿,请将方法进行拆分,主方法负责核心流程,分方法负责具体单个功能点的实现;
  • 一个Class类应该只负责一个明确的职责,不要想一个Class把所有事情都做了,比如一个服务层的类,不要把数据层的功能都写在一起
  • 一个包应该只负责一个方面的职责,比如dao包下面就是负责数据层服务的

优点:便于扩展;可读性高

1.3 依赖倒置原则(Dependence Inversion Principle,DIP)

设计思想:高层模块不应该依赖底层模块,应该依赖其抽象

含义:面向接口编程,不要面向实现,比如服务模块代码会使用数据模块的功能,那么服务模块应该内聚的是数据模块的抽象,而不是具体的数据模块实现,这样可以避免因数据模块实现的变动,而导致服务模块的改变。经典应用:Spring的IOC

优点:便于扩展;

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

设计思想:接口设计应该具备单一责任要求,即多个单一责任接口替换多责任接口

含义:子类避免继承接口后,被迫实现一些自己不需要的功能,哪怕是空实现,也代表接口设计出现责任非单一的问题。应该把接口细化,按功能划分为多类接口。

优点:便于扩展;可读性高

1.5 迪米特原则(Law of Demeter LoD)/最少知道原则(LKP)

设计思想:一个对象应该对其他对象保持最少的了解

含义:

  • 避免无关的依赖,比如A依赖B实现某个功能,B又需要依赖C,那么A完全没必要知道C的存在,那C就不要已中间对象的形式出现在A的功能实现中;
  • 控制方法访问权限,即public,protect,default,private,如果方法私有那么一定是private,请按最小原则控制对象的访问权限,对外部对象,应按需暴露方法和属性,越少越好;

优点:便于扩展;可读性高;

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

设计思想:所有引用基类的地方必须能替换为它的任意子类对象,且程序执行效果“不变 ”

含义:子类不要重写父类的非抽象方法,父类只实现通用方法即可。尽量保证继承的有意义,不要乱用继承,来实现非继承功能。其实就是少修改,多扩展,也是开闭原则的体现。

优点:可扩展性;可读性高;

1.7 合成复用原则(Composite/Aggregate Reuse Principle,CARP)

设计思想:尽量使用对象组合(has-a)/聚合(contanis-a),而不是继承关系达到功能复用的目的

含义:里氏替换是强调合理使用继承,如果出现继承无法满足的时候,采用合成复用的方式,而不要去破坏原本的继承关系。

优点:可扩展性;可读性高;

总体来说,都是为了可扩展性和可读性,

核心思想:开闭和单一;

实现方式:依赖倒置、接口隔离、最少知道;

关系约定:里氏替换、合成复用;

2 设计模式:设计原则的体现


2.1 单例模式

  • 单一责任:单例么,只负责生产一个产品,有且只有一个功能

2.2 工厂方法|抽象工厂:

  • 开闭原则:工厂定义构建产品的超类的通用方法不变,子类工厂扩展实现构建不同子类产品的方法
  • 单一责任:每个子类工厂只负责一个类型的产品生产
  • 依赖倒置:工厂依赖的是产品的抽象,而不是产品的实现

2.3 建造者模式

  • 开闭原则:构建方式不变,但可以扩展实现构建的子项
  • 依赖倒置:建造者依赖的是子项的抽象
  • 合成复用:建造者通过组合子项的方式来扩展功能

2.4 原型模式

  • 单一责任:原型实现克隆接口,仅负责克隆一件事情

2.5 适配器模式

  • 开闭原则:提供功能的对象(A)不变,适配目标(B)不变,扩展实现一个适配器(C)使用A来实现目标B的功能
  • 单一责任:提供功能的对象,适配目标对象,适配器对象,各自职责唯一
  • 合成复用:适配器组合了提供功能的对象

2.6 桥梁模式

  • 开闭原则:当部分功能实现有自己的一套扩展机制,为了保证抽象的不变性,让实现化的部分独立扩展
  • 单一责任:抽象化与实现化的分离,使得两者责任单一,可以自由发展
  • 合成复用:抽象化对象聚合实现化对象,从而获得实现化对象的功能
  • 接口隔离:这个体现的太明显了
  • 依赖倒置:抽象化对象的抽象依赖实现化对象的超类

2.7 树组模式

  • 开闭原则:树组结构不变,通过继承体系自由扩展
  • 合成复用:对象本身聚合对象的集合,构成父子节点关系

2.8 装饰者模式

  • 开闭原则:装饰结构不变,面向变化扩展的经典实现
  • 合成复用:对象本身通过聚合同类对象,实现了功能的扩展
  • 单一责任:每一个装饰者仅负责自己独立的功能

2.9 门面模式

  • 开闭原则:门面本身对外接口不变,内部通过扩展来应对变化
  • 合成复用:门面聚合各类子功能的实现对象
  • 单一责任:门面干门面的活,子功能干子功能的事

2.10 享元模式

  • 合成复用:享元对象聚合共享对象的集合
  • 单一责任:享元对象仅提供访问共享对象的入口,各种功能实现由共享对象完成

2.11 代理模式

  • 合成复用:代理对象聚合被代理的对象,从而可以控制被代理对象的功能执行过程
  • 单一责任:代理仅负责控制执行过程,不做功能上的附加操作

2.12 责任链模式

  • 开闭原则:链表的结构不变,但可以自由的扩展不同的实现
  • 单一责任:每个责任链的节点只负责单一的功能
  • 合成复用:每个责任链的节点会聚合下一个责任链的节点

2.13 命令模式

  • 单一责任:命令、调用者、执行者,各自负责自己的功能
  • 合成复用:命令对象聚合执行者对象,调用者对象聚合命令对象
  • 最少知道:调用者与执行者解耦,因为通常调用者无需知道执行者的所有行为,他只需知道当前执行的命令相关信息即可

2.14 解释器模式

  • 单一责任:就干翻译这一件事,对于被翻译对象而言,他没必要再提供翻译相关的实现,将这个实现交给翻译器即可

2.15 迭代器模式

  • 单一责任:就负责迭代访问数据
  • 开闭原则:迭代方式通用不变,各个集合实现各自的迭代需求
  • 合成复用:每个迭代器默认聚合各自的集合类,通过集合类本身方法实现迭代功能,也是一种适配模式
  • 接口隔离:相对于统一的集合接口,他把迭代实现分离

2.16 中介者模式

  • 单一责任:嘿嘿,中介就是个负责对象间关系的
  • 开闭原则:中介处理关系不变,中介负责的对象,可以自由扩展
  • 合成复用:中介聚合相关的对象

2.17 备忘录模式

  • 单一责任:为对象信息持久化提供功能,仅此一个功能哦

2.18 观察者模式

  • 合成复用:观察者聚合被观察主题(主动获取主题变化);被观察主题聚合被观察者集合(主题主动通知观察者)
  • 依赖倒置:两者之间皆是聚合抽象

2.19 状态模式

  • 合成复用:对象聚合状态抽象,来实现不同状态下的行为
  • 依赖倒置:对象聚合状态的抽象,而非实现

2.20 策略模式

  • 合成复用:对象聚合策略抽象,来实现不同策略下的行为
  • 依赖倒置:对象聚合策略的抽象,而非实现

2.21 模板方法模式

  • 开闭原则:模板抽象通用方法不变,差异化部分,由子类扩展实现
  • 里氏替换:父类只实现通用方法,很明显的原则体现

2.22 访问者模式

  • 责任单一:访问者就是负责临时“访问”功能,被用于其他对象方法参数依赖

3 总结


心怀扩展,代码易读,原则为本,模式为法。

多读源码!多思考!多动手!gogogo!


爱家人,爱生活,爱设计,爱编程,拥抱精彩人生!

发布了96 篇原创文章 · 获赞 237 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qqchaozai/article/details/103512530