设计模式——概要

一、设计模式概括

设计模式是对大家实际工作中写的各种代码进行高层次抽象的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。,其中最出名的当属Gang of Four (GoF) 的分类了,他们将设计模式分类为23 种经典的模式,根据用途我们又可以分为三大类

  1. 创建型模式(Creational Patterns)共五种
  2. 结构型模式(Structural Patterns)共七种
  3. 行为型模式(Behavioral Patterns)共十一种

(一)创建型模式(Creational Patterns)

主要关注在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。将对象的创建于使用分离,这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。

  • 创建型模式的作用就是创建对象,说到创建一个对象,最熟悉的就是 new 一个对象,然后 set 相关属性。但是,在很多场景下,我们需要给客户端提供更加友好的创建对象的方式,尤其是那种我们定义了类,但是需要提供给其他开发者用的时候
模式 英文 一句话总结
工厂模式(常见) Factory Pattern 由子类来决定创建具体对象
抽象工厂模式(常见) Abstract Factory Pattern 允许使用者创建对象的家族,无需指定具体类
单例模式(常见) Singleton Pattern 只为对象提供一个全局的访问点(世上只有一个地球)
建造者模式 Builder Pattern 允许使用者自由搭配组合对象
原型模式(常见) Prototype Pattern 通过复制原对象来创建新对象

简单工厂模式Simple Factory Pattern–不属于标准的设计模式)

(二)结构型模式(Structural Patterns)

主要关注类和对象的组合。虽然面向对象的继承机制提供了最基本的子类扩展父类的功能,但结构型模式不仅仅简单地使用继承,而更多地通过组合与运行期的动态组合来实现更灵活的功能。

模式 英文 一句话总结
适配器模式(常见) Adapter Pattern 兼容转换(我所做的一切,只是为了配得上你)
兼容客户类对目标类的调用,使客户类能够按自己期望的方式调用目标类
桥接模式(桥梁模式) Bridge Pattern 将抽象与具体分离开来
装饰器模式(常见) Decorator Pattern 在不修改原对象的情况下为对象附加新的功能
代理模式(常见) Proxy Pattern 增强对象功能
外观模式(门面模式) Facade Pattern 统一访问入口(拨开云雾见天日)
组合模式 Composite Pattern 以树形结构统一整体和个体的处理方式
享元模式 Flyweight Pattern 共享资源池(节省资源,从我做起)

(三)行为型模式(Behavioral Patterns)

行为型模式 关注对象之间的通信。 通过使用对象组合,使一组对象协作来完成一个整体任务。

模式 英文 一句话总结
策略模式(常见) Strategy Pattern 定义可互相替换策略,使用者爱用哪个用哪个(条条道路通罗马)
模板模式 (常见) Template Pattern 定义完整流程,只允许子类微调
观察者模式(常见) Observer Pattern 解耦观察者和被观察者,状态发生改变时主动通知观察者
迭代器模式 Iterator Pattern 统一对集合的访问方式
责任链模式 (常见) Chain of Responsibility Pattern 链路上每个对象只处理自己能处理的(个人自扫门前雪,休管他人瓦上霜)
命令模式 Command Pattern 将请求与处理进行解耦(运筹帷幄之中,决胜千里之外)
备忘录模式 Memento Pattern 备份对象(专卖“后悔药”)
状态模式 State Pattern 绑定状态和行为
访问者模式(常见) Visitor Pattern 解耦数据结构和数据操作
中介者模式 (常见) Mediator Pattern 将网状结构统一通过中介进行管理
解释器模式 Interpreter Pattern 实现特定语法的解析(我的地盘我做主)

(四)使用设计模式的好处

  1. 代码重用性 :即相同功能的代码,不用多次编写
  2. 可读性 :即编程规范性, 便于其他程序员的阅读和理解
  3. 可扩展性 :即当需要增加新的功能时,非常的方便,也称为可维护性
  4. 可靠性 :即当我们增加新的功能后,对原来的功能没有影响
  5. 使程序呈现高内聚,低耦合的特性 , 模块内部紧密,但模块间依赖小,一者出错不影响他者

(五)设计模式之间的关系

二、软件设计的七大原则

(一)开闭原则(Open Close Principle,OCP)(总原则)

开闭原则(Open Close Principle,OCP):开放扩展、关闭修改。抽象出接口,通过实现接口 或 继承类进行扩展,但尽量不要修改接口。

  • 一句话: 对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用 "接口" 和 "抽象类"
  • 开闭原则是编程中最基础、最重要的设计原则。编程中遵循其它原则,以及使用设计模式的目的就是遵循开闭原则。
    • 一个类应该对扩展开放(对提供方),对修改关闭(对使用方)。也就是需要变化时,尽量通过重新派生一个实现类来实现变化,而不是通过修改已有的代码来实现变化。用抽象构建框架,用实现扩展细节。

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

单一职责原则(Single Responsibility Principle,SRP):一个类、接口、方法只负责一项功能,降低因为类的复杂度、变更引起的风险,提高类的可读性,易于维护。

  • 一句话: 一个类只负责一项职责
  • 如类A负责两个不同职责:职责1,职责2。当职责1需求变更而改变类A时,可能造成职责2执行错误,所以需要将类A的分解为A1、A2
  • 通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单,才可以在代码违反单一职责原则只有类中方法数量足够少,可以在方法级别保持单一职责原则

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

里氏替换原则(Liskov Substitution Principle,LSP):父类对象都可以替换为子类对象,即父类适用的地方,子类也应该适用

  • 一句话: 子类可以扩展父类的功能,但不能改变父类原有的功能,换句话说,子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写父类的方法。
    • 继承实际上让两个类耦合性增强了,如果通过重写父类的方法来完成新的功能,这样写起来虽然简单,但是整个继承体系的可复用性会比较差,特别是运用多态比较频繁时,程序运行出错的概率会非常大。
  • 总结的几条原则:
  • 1.子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法。
  • 2.子类中可以增加自己的特有方法。
  • 3.当子类方法重载父类的方法时,方法的前置条件(即方法的输入/入参)要比父类方法输入的参数更宽松
  • 4.当子类实现父类的方法(重载/重写/实现抽象方法),方法的后置条件(即方法的输出/返回值)要比父类更严格或者相等

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

依赖倒置原则(Dependence Inversion Principle,DIP):高层某块不应该依赖低层模块的具体实现,而是依赖低层模块的接口,将耦合度降低到接口层次

  • 一句话: 要依赖于抽象,不要依赖于具体实现,核心思想是面向接口编程依赖倒转原则是对开闭原则的具体实现
  • 依赖倒转(倒置)的中心思想是面向接口编程,所谓“倒转”是指抽象不应该依赖具体实现,而是具体实现应该依赖抽象。也就是高层模块不应该依赖低层模块,二者都应该依赖其抽象。因为相对于具体实现的多变性,抽象的东西要稳定的多。

(五)接口隔离原则(Interface Segregation Principle)

接口隔离原则(Interface Segregation Principle):接口之间相互独立,尽量通过接口来访问

  • 一句话: 建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少
  • 比如:类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口接口I对于类A和类C来说不是最小接口,那么类B和类D必须去实现他们不需要的方法

(六)迪米特原则(Demeter Principle)

迪米特原则,又称最少知道原则(Demeter Principle):使用其它模块时只关心暴露出来的接口,不关系内部的具体实现

  • 一句话: 一个对象应该对其他对象保持最少的了解,和朋友交流,不和陌生人(非直接朋友)说话。
  • 即一个类对自己依赖的类(自己使用的类)知道的越少越好,核心是降低类之间的耦合。也就是说,对于被依赖的类(被使用的类)不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的public 方法,不对外泄露任何信息。
    • 避免与非直接朋友的耦合,只与直接的朋友通信,所谓的 “直接朋友” 是指出现在当前类成员变量方法参数方法返回值中的类。而 “非直接朋友”是指出现在局部变量中的类。也就是说,陌生的类最好不要以 "局部变量" 的形式出现在类的内部。
      • 成员变量:定义在方法外
      • 局部变量:定义在代码块、方法参数列表、方法体内

(七)合成复用原则(Composite Reuse Principle)

组合复用原则,又称组合/聚合复用原则(Composite Reuse Principle):要尽量先使用组合或者聚合关联关系来代替继承实现复用,这样可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少。 

  • 一句话: 尽量使用依赖、组合、聚合的方式,而不是使用继承。
  • 继承 通常也称之为白箱复用,相当于把所有的实现细节暴露给子类。组合/聚合 也称之为黑箱复用,对类以外的对象是无法获取到实现细节的。
posted @ 2022-12-16 17:19  ImreW  阅读(38)  评论(0编辑  收藏  举报