- 一.定义
- 二.作用
- 三.设计原则
- 四.分类
- 1.创建型
- 2.结构型
- 3.行为型
- 3.1.责任链模式(Chain of Responsibility Pattern)
- 3.2.命令模式(Command Pattern)
- 3.3.解释器模式(Interpreter Pattern)
- 3.4.迭代器模式(Iterator Pattern)
- 3.5.中介者模式(Mediator Pattern)
- 3.6.备忘录模式(Memento Pattern)
- 3.7.观察者模式(Observer Pattern)
- 3.8.状态模式(State Pattern)
- 3.9.空对象模式(Null Object Pattern)
- 3.10.策略模式(Strategy Pattern)
- 3.11.模板模式(Template Pattern)
- 3.12.访问者模式(Visitor Pattern)
参考:
- 手把手带你深入浅出神秘的设计模式
- 菜鸟教程-设计模式
- 《Android源码设计模式解析与实战》
一.定义
设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。
二.作用
使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。
1.提高代码复用率,降低开发成本和周期 2.提高代码可维护性、可拓展性 3.使代码更加优雅 4.让代码更容易被他人理解
三.设计原则
- 对接口编程而不是对实现编程。
-
1.单一职责
定义:一个类应该只有一个发生变化的原因
- 白话:如果一个类承担的职责过多,即耦合性太高=一个职责的变化可能会影响到其他的职责
特点
- 降低类的复杂性, 对类或接口的职责有清晰明确定义;
- 提高可读性;
- 提高可维护性;
- 降低变更引起的风险, 接口改变只影响相应的实现类, 不影响其他类;
- 重点
- 接口一定要做到单一职责;
- 类的单一职责比较难以实现, 尽量做到只有一个原因引起变化;
- 一个方法尽可能做一件事, 能分解就分解, 分解到原子级别;
补充:
定义:软件中的对象(类, 模块, 函数)应该对扩展开放, 对修改关闭;
- 即软件实体应该通过扩展实现变化, 不是通过修改已有的代码实现变化;
- 符合开放封闭原则的最好方式是提供一个固有的接口,然后让所有可能发生变化的类实现该接口,让固定的接口与相关对象进行交互。
优点
- 利于测试:如果改变软件内容, 需要将所有的测试流程都执行一遍, 如 单元测试, 功能测试, 集成测试等, 如果只是扩展, 只单独测试扩展部分即可;
- 提高可维护性 : 维护一个类最好的方式是 扩展一个类, 而不是修改一个类, 如果需要修改需要读懂源码才能修改, 扩展的话只需要了解即可, 直接继承扩展;
补充:
定义:所有 引用基类的地方 必须能 透明地使用其子类的对象;
- 白话:只要 父类出现的地方子类就可以出现, 替换为子类也不会产生任何错误, 使用者不需要知道父类还是子类;
- 需求(场景):玩家玩射击气球游戏,他既能使用AK仿真枪,也可以使用步枪还可以使用手枪射击气球。
在软件开发过程中,子类替换父类后,程序的行为是一样的。
- 只有当子类替换掉父类后软件的功能不受影响时,父类才能真正地被复用,而子类也可以在父类的基础上添加新的行为。
- 特点:
- 里氏替换原则核心是继承,同样它的优缺点也是继承的优缺点;
- 继承的优缺点(补充)
- 优点
- 代码共享 : 共享代码, 子类都拥有父类的方法和属性, 将 父类的代码共享给了子类;
- 重用性 : 提高代码的重用性, 子类重用父类的代码;
- 子父类异同 : 子类形似父类, 异于父类, 父子都不同;
- 扩展性 : 提高代码的可扩展性, 子类就可以为所欲为了, 子类可以随意扩展父类;
- 开放性 : 提高产品或项目的开放性, 父类随意扩展, 开放性随之增加了;
- 缺点
- 侵入性 : 继承是侵入性的, 子类 强制继承 父类的方法和属性;
- 灵活性 : 降低代码的灵活性, 子类必须拥有父类的属性和方法, 子类受到了父类的约束, 这是从子类的角度讲得;
- 耦合性 : 增强了耦合性, 父类的属性和方法被修改时, 还需要顾及其子类, 可能会带来大量的重构, 这是从父类的角度讲的;
- 优点
补充
定义:依赖于抽象而不依赖于具体。
- 针对接口编程,开闭原则的基础;
高层模块不应该依赖低层模块,抽象不应该依赖细节,高层模块和细节应该都依赖其抽象。
- 所谓的 “面向接口编程,而不是面向实现编程”。这样可以降低客户与具体实现的耦合。
- 补充:**
优点
- 减少类之间的耦合
- 提高系统稳定性
- 降低并发风险
- 提高代码可读性
- 依赖注入的实现(略)
- 构造函数:通过 构造函数参数 声明依赖对象;
- Setter方法:通过 Setter 函数 参数 声明依赖对象;
- 接口注入依赖对象:在接口方法的参数中声明依赖对象;
- 依赖倒置本质
- 通过 抽象 即 接口或者抽象类, 使 各个类 和 模块实现彼此独立, 实现模块间 松耦合;
- 使用场景
- 依赖倒置在小项目中得有点很难体现出来, 是否采用依赖倒置原则影响不大;
- 项目越大, 需求改变越多, 采用依赖倒置原则设计的接口或抽象类 对 实现类的约束, 会大大减少维护成本;
补充
使用多个专门功能的接口,而不是使用单一的总接口。
- 不要让一个单一的接口承担过多的职责,而应把每个职责分离到多个专门的接口中,进行接口分离。
单一职责 与 接口隔离 区别 :
- 单一原则 注重职责, 注重业务逻辑上得划分;
- 接口隔离 注重的是接口的方法尽量少;
- 特点
- 接口尽量小:拆分接口 ,接口隔离的核心定义, 不出现臃肿的接口;
- 接口高内聚:高内聚 ,提高接口, 类, 模块的处理能力, 减少对外界交互;
- 具体方法 : 接口中尽量少公布public 方法, 对外公布的 public 方法越少, 变更的风险就越小, 有利于后期的维护;
- 原子接口划分原则
- 接口模块对应关系 : 一个接口只服务于一个子模块 或 业务逻辑;
- 方法压缩 : 通过业务逻辑, 压缩接口中的 public 方法, 减少接口的方法的数量;
- 修改适配 : 尽量去修改已经污染的接口, 如果变更风险较大, 采用适配器模式进行转化处理;
补充
在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分。
- 新对象通过向这些对象的委派达到复用已用功能的目的。
- 简单地说,就是要尽量使用合成/聚合,尽量不要使用继承。
7.迪米特(最少知道)
一个模块或对象应尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立,这样当一个模块修改时,影响的模块就会越少,扩展起来更加容易。
- 关于迪米特法则的其他描述:只与你直接的朋友们通信;不要跟“陌生人”说话。
- 外观模式(Facade Pattern)和中介者模式(Mediator Pattern)就使用了迪米特法则。
设计方法
- 一个类的 public 方法越多, 修改时涉及的范围也就越大, 变更引起的风险也就越大, 在系统设计时要注意, 能用 private 就用private , 能用 protected 就用 protected, 能少用 public 就少用 public, 能加上 final 就加上 final;
优缺点
在应用开发过程中,最难的不是完成应用的开发工作。而是在后续的升级、维护过程中让应用系统能够拥抱变化。拥抱变化就意味着在满足需求且不破坏系统稳定性的前提下保持高拓展性、高内聚、低耦合,在经历了个版本的变更之后依然保持清晰、灵活、稳定的系统架构。当然,这是比较理想的状态,我们需要朝着这个目标去做,最好的方式就是遵循以上的设计原则。
四.分类
1.创建型
不是使用 new 运算符直接实例化对象,而是提供一种方式-在创建对象的同时隐藏创建逻辑;
好处:这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。
1.1.工厂模式(Factory Pattern)
1.2.抽象工厂模式(Abstract Factory Pattern)
1.3.单例模式(Singleton Pattern)
1.4.建造者模式(Builder Pattern)
1.5.原型模式(Prototype Pattern)
2.结构型
-
2.1.适配器模式(Adapter Pattern)
2.2.桥接模式(Bridge Pattern)
2.3.过滤器模式(Filter、Criteria Pattern)
2.4.组合模式(Composite Pattern)
2.5.装饰器模式(Decorator Pattern)
2.6.外观模式(Facade Pattern)
2.7.享元模式(Flyweight Pattern)
2.8.代理模式(Proxy Pattern)
3.行为型
-
3.1.责任链模式(Chain of Responsibility Pattern)
定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系,
将这些对象形成一条链,并沿着这条链传递该请求,直到有对象处理它为止;
- 重点:上一个处理对象必须含有下一个处理对象的引用,形成一个单向链表;
3.2.命令模式(Command Pattern)
3.3.解释器模式(Interpreter Pattern)
3.4.迭代器模式(Iterator Pattern)
3.5.中介者模式(Mediator Pattern)
3.6.备忘录模式(Memento Pattern)
3.7.观察者模式(Observer Pattern)
3.8.状态模式(State Pattern)
3.9.空对象模式(Null Object Pattern)
3.10.策略模式(Strategy Pattern)
3.11.模板模式(Template Pattern)
3.12.访问者模式(Visitor Pattern)