设计模式总结说明

设计模式总结

一 单例模式(一个对象)

  1. 目的
    保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法
  2. 八种方式
    (1) 饿汉式(静态常量)
    (2)饿汉式(静态代码块)
    (3)懒汉式(线程不安全)
    (4)懒汉式(线程安全,同步方法)
    (5)懒汉式(线程安全,同步代码块)
    (6)双重检查(推荐使用)
    (7)静态内部类(推荐使用)
    (8)枚举(推荐使用)
  3. JDK中的Runtime就是经典的单例模式
    在这里插入图片描述
  4. 使用场景
    需要频繁的进行创建和销毁的对象、创建对象时耗时过多或耗费资源过多(即:重量级对象),但又经常用到的对象、工具类对象、频繁访问数据库或文件的对象(比如数据源、session 工厂等)
  5. 具体内容博客
    单例模式

二 工厂模式(创建对象方法)

  1. 三种模式
    (1)简单工厂模式(静态工厂模式)
    **定义一个可以实例化对象的简单工厂类,封装创建对象的代码方法(获取对象)**可以创建不同的简单工厂类。
    (2)工厂方法模式
    定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。
    (3)抽象工厂模式
    定义了一个 interface,用于创建相关或有依赖关系的对象簇,而无需指明具体的类,抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。从设计层面看,抽象工厂模式就是对简单工厂模式的改进。将工厂抽象成两层,AbsFactory(抽象工厂) 和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。
  2. JDK中的Calendar类就使用了简单工厂模式
    在这里插入图片描述
  3. 工厂模式小结
    目的:将实例化对象的代码提取出来,放到一个类中统一管理和维护
    ① 创建对象实例时,不要直接 new 类, 而是把这个 new 类的动作放在一个工厂的方法中,并返回。有的书上说,变量不要直接持有具体类的引用。
    ② 不要让类继承具体类,而是继承抽象类或者是实现 interface(接口)
    ③ 不要覆盖基类中已经实现的方法。
  4. 工厂模式具体内容
    工厂模式

三 原型模式(拷贝)

  1. 介绍
    原型模式(Prototype 模式)是指:用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象
  2. 原理
    通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建,即 对象.clone()
    在这里插入图片描述
  3. spring框架中bean的创建就是使用原型模式
    在这里插入图片描述
  4. 浅拷贝和深拷贝
    (1)浅拷贝
    ① 数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,就是把属性值复制一份给新的对象
    ② 数据类型是引用类型的成员变量,浅拷贝会进行**引用传递,就是把成员变量的引用地址复制一份给新的对象。**这种情况下,一个对象中的成员变量发生修改,另外一个对象也会修改。
    ③ 浅拷贝是使用默认的clone方法来实现的
    (2)深拷贝
    重写clone方法实现深拷贝
    使用序列化实现深拷贝(推荐)
  5. 原型模式具体内容
    原型模式

四 建造者模式(抽象创建对象过程)

  1. 介绍
    将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象
  2. 四个角色
    (1)Product(产品角色):一个具体的产品对象
    (2)Builder(抽象建造者):创建一个Product对象的各个部件指定的接口/抽象类
    (3)ConcreteBuilder(具体建造者):实现接口,构建和装配各个部件
    (4)Director(指挥者):构建一个使用Builder接口的对象,用于创建一个复杂的对象,一是隔离客户和对象的生产过程,二是负责控制产品对象的生产过程。
  3. 原理类图
    在这里插入图片描述
  4. JDK的StringBuilder使用了建造者模式
    在这里插入图片描述
  5. 建造者模式具体内容
    建造者模式

五 适配器模式(目标与被适配者通过适配器转换)

  1. 介绍
    适配器模式(Adapter Pattern)**将某个类的接口转换成客户端期望的另一个接口表示,**主要目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)
  2. 工作原理
    将一个类的接口转换成另一种接口.让原本接口不兼容的类可以兼容。用户调用适配器转化出来的目标接口方法,适配器再调用被适配者的相关接口方法
    在这里插入图片描述
  3. 三种分类
    (1)类适配器模式
    Adapter 类,通过继承 src 类,实现 dst 类接口,完成 src->dst 的适配
    (2)对象适配器模式
    Adapter 类持有 src 类,实现 dst 类接口,完成 src->dst 的适配
    (3)接口适配器模式
    当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求
  4. SpringMVC的HandlerAdapter使用了适配器模式
    (1)源码
    在这里插入图片描述
    (2)UML类图
    在这里插入图片描述
  5. 适配器模式具体内容
    适配器模式

六 桥接模式(抽象与行为实现独立)

  1. 介绍
    桥接模式是指将实现与抽象放在两个不同的类层次中,使两个层次可以独立改变。基于类的最小设计原则,通过使用封装、聚合及继承等行为让不同的类承担不同的职责。它的主要特点是把抽象(Abstraction)与行为实现(Implementation)分离开来,抽象类聚合实现接口类,从而可以保持各部分的独立性以及应对他们的功能扩展
  2. 原理类图
    在这里插入图片描述
  3. JDBC的Driver使用了桥接模式
    (1)源码
    在这里插入图片描述
    (2)原理类图
    此处不是正规的桥接模式,没有抽象类
    在这里插入图片描述
  4. 桥接模式具体内容
    桥接模式

七 装饰者模式(抽象主体类和主体被装饰者和装饰者)

  1. 介绍
    动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)
  2. 原理
    在这里插入图片描述
    说明:
    (1)装饰者模式就像打包一个快递,东西就是被装饰者,纸箱就是装饰的
    (2)Component 主体:比如类似前面的 Drink
    (3)ConcreteComponent :具体的主体,比如前面的各个单品咖啡
    (4)Decorator: 装饰者,比如各调料
    (5)表现形式:new 装饰者类(new 被装饰者类)
    例如:new DataInputStream(new FileInputStream(“d://aa.txt”))
    在这里插入图片描述
  3. JDK中IO结构的FilterInputStream使用装饰者模式
    在这里插入图片描述
  4. 装饰者模式具体内容
    装饰者模式

八 组合模式(树形结构组合对象)

  1. 基本介绍
    组合模式依据树形结构来组合对象,用来表示部分以及整体层次。使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象。需要遍历组织机构,或者处理的对象具有树形结构时, 非常适合使用组合模式
  2. 原理类图
    在这里插入图片描述
  3. JDK中的的HashMap使用了组合模式
    (1)源码
    在这里插入图片描述
    (2)类图
    在这里插入图片描述
  4. 组合模式具体内容
    组合模式

九 外观模式(过程模式,子系统,统一接口)

  1. 基本介绍
    外观模式(Facade),也叫“过程模式:外观模式为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用
  2. 原理类图
    在这里插入图片描述
  3. Mybatis中Configuration创建MetaObject使用外观模式
    (1)源码
    在这里插入图片描述
    (2)类图
    在这里插入图片描述
  4. 外观模式具体内容
    外观模式

十 享元模式(外部,内部共享状态,池)

  1. 基本介绍
    享元模式(Flyweight Pattern) 也叫 蝇量模式: 运用共享技术有效地支持大量细粒度的对象。常用于系统底层开发,解决系统的性能问题。像数据库连接池,里面都是创建好的连接对象,在这些连接对象中有我们需要的则直接拿来用,避免重新创建,如果没有我们需要的,则创建一个。
  2. 原理类图
    在这里插入图片描述
    说明:
    (1)FlyWeight 是抽象的享元角色, 他是产品的抽象类, 同时定义出对象的外部状态和内部状态(后面介绍) 的接口或实现
    (2)ConcreteFlyWeight 是具体的享元角色,是具体的产品类,实现抽象角色定义相关业务
    (3)UnSharedConcreteFlyWeight 是不可共享的角色,一般不会出现在享元工厂
    (4)FlyWeightFactory 享元工厂类,用于构建一个池容器(集合), 同时提供从池中获取对象方法
  3. JDK中Integer的valueOf()方法使用了享元模式
    在这里插入图片描述
    说明:
    (1) 在 valueOf 方法中,先判断值是否在IntegerCache 中,如果不在,就创建新的Integer(new), 否则,就直接从 缓存池返回
    (2) valueOf 方法,就使用到享元模式
    (3) 如果使用 valueOf 方法得到一个 Integer 实例,范围在 -128 - 127 ,执行速度比 new 快

十一 代理模式(代理对象,中介)

  1. 基本介绍
    为一个对象提供一个替身,以控制对这个对象的访问。即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。
  2. 原理类图
    在这里插入图片描述
  3. 三种形式
    (1)静态代理
    ① 基本介绍
    定义接口或者父类,被代理对象(即目标对象)与代理对象一起实现相同的接口或者是继承相同父类
    ② 实现步骤
    Ⅰ 定义一个接口或父类
    Ⅱ 目标对象类实现接口或继承父类
    Ⅲ 代理类实现接口或继承父类并聚合目标对象
    Ⅳ 执行方法

    (2)动态代理(JDK代理)
    ① 基本介绍
    代理对象,不需要实现接口,但是目标对象要实现接口,否则不能用动态代理,代理对象的生成,是利用 JDK 的 API,动态的在内存中构建代理对象,动态代理也叫做:JDK 代理、接口代理
    ② 具体步骤
    Ⅰ创建接口
    Ⅱ 创建目标类实现接口
    Ⅲ 创建代理类ProxyFactory聚合目标对象,并使用newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)重写invoke方法,生成代理对象
    Ⅳ 执行方法

    (3)Cglib代理
    ① 基本介绍
    Cglib代理也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能扩展, 有些书也将Cglib代理归属到动态代理,Cglib 包的底层是通过使用字节码处理框架 ASM 来转换字节码并生成新的类
    ② 具体步骤
    Ⅰ 自定义一个类
    Ⅱ 创建代理类ProxyFactory 实现MethodInterceptor接口并重写intercept方法,聚合目标对象
    Ⅲ 创建方法getProxyInstance(),在方法内通过Enhancer对象的create方法进行设置父类、回调函数获取代理对象等操作
  4. 代理模式具体内容
    代理模式

十二 模板方法模式(模板方法,钩子函数,抽象方法)

  1. 基本介绍
    (1)模板方法模式,又叫模板模式,在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。
    (2)模板方法模式使用场景:当要完成在某个过程,该过程要执行一系列步骤 ,这一系列的步骤基本相同,但其个别步骤在实现时 可能不同,通常考虑用模板方法模式来处理
  2. 原理类图
    在这里插入图片描述
    说明;
    (1)AbstractClass 抽象类, 类中实现了final定义的模板方法(template),里面包括一些公共的方法,不让子类覆盖,定义了算法的骨架,具体子类需要去实现 其它的抽象方法 operationr2,3,4
    (2)ConcreteClass 实现抽象方法 operationr2,3,4, 以完成算法中特点子类的步骤
  3. Spring IOC容器初始化使用模板方法
    (1)源码
    在这里插入图片描述
    (2)类图
    在这里插入图片描述
    说明:
    (1)AbstractApplicationContext为抽象类,类似于上面的SoyaMilk,含有模板方法和钩子函数
    (2)refresh方法为模板方法
    (3)refreshBeanFactory和getBeanFactory为抽象方法,由子类实现
    (4)postProcessBeanFactory和onRefresh是钩子函数,可以由子类决定是否覆盖
  4. 模板方法具体内容
    模板方法模式

十三 命令模式(动作的请求和执行及命令)

  1. 基本介绍
    (1)命令模式:在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计。
    (2)在命名模式中,会将一个请求封装为一个对象,以便使用不同参数来表示不同的请求(即命名),同时命令模式也支持可撤销的操作
  2. 原理类图
    在这里插入图片描述
    说明:
    (1)Invoker 是调用者角色
    (2)Command: 是命令角色,需要执行的所有命令都在这里,可以是接口或抽象类
    (3)Receiver: 接受者角色,知道如何实施和执行一个请求相关的操作
    (4)ConcreteCommand: 将一个接受者对象与一个动作绑定,调用接受者相应的操作,实现 execut
  3. Spring的JdbcTemplete使用了命令模式
    (1)代码
    在这里插入图片描述
    (2)角色说明
    ① StatementCallback接口,类似于命令接口(command)
    ② class QueryStatementCallback implements StatementCallback, SqlProvider , 匿名内部类, 实现了命令接口,同时也充当命令接收者
    ③ 命令调用者 是 JdbcTemplate , 其中execute(StatementCallback action) 方法中,调用 action.doInStatement 方法. 不同的 实现StatementCallback 接口的对象,对应不同的doInStatemnt 实现逻辑
    ④ 实现 StatementCallback 命令接口的子类还有如图所示
    在这里插入图片描述
  4. 命令模式具体内容
    命令模式

十四 访问者模式(稳定的数据结构和变动的功能需求)

  1. 基本介绍
    访问者模式(Visitor Pattern),封装一些作用于某种数据结构的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作,主要将数据结构与数据操作分离,解决数据结构和操作耦合性问题
  2. 工作原理
    在被访问的类里面加一个对外提供接待访问者的接口
    在这里插入图片描述
    说明:
    (1)Visitor 是抽象访问者,为该对象结构中的ConcreteElement 的每一个类声明一个 visit 操作
    (2)ConcreteVisitor :是一个具体的访问值 实现每个有 Visitor 声明的操作,是每个操作实现的部分
    (3)ObjectStructure 能枚举它的元素, 可以提供一个高层的接口,用来允许访问者访问元素
    (4)Element 定义一个 accept 方法,接收一个访问者对象
    (5)ConcreteElement 为具体元素,实现了 accept 方法
  3. 使用场景
    访问者模式可以对功能进行统一,可以做报表、UI、拦截器与过滤器,适用于数据结构相对稳定的系统 如果一个系统有比较稳定的数据结构,又有经常变化的功能需求,那么访问者模式就是比较合适的
  4. 具体内容
    访问者模式

十五 迭代器模式(集合迭代遍历)

  1. 基本介绍
    提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示,即:不暴露其内部的结构
  2. 原理类图
    在这里插入图片描述
    说明:
    (1)Iterator : 迭代器接口,是系统提供,含义 hasNext, next, remove
    (2)ConcreteIterator : 具体的迭代器类,管理迭代
    (3)Aggregate :一个统一的聚合接口, 将客户端和具体聚合解耦
    (4)ConcreteAggreage : 具体的聚合持有对象集合, 并提供一个方法,返回一个迭代器, 该迭代器可以正确遍历集合
    (5)Client :客户端, 通过 Iterator 和 Aggregate 依赖子类
  3. JDK的ArrayList集合使用了迭代器模式
    在这里插入图片描述
    在这里插入图片描述
    说明:
    (1)Iterator 接口系统提供
    (2)List 就是充当了聚合接口,含有一个 iterator() 方法,返回一个迭代器对象
    (3)内部类 Itr 充当具体实现迭代器 Iterator 的类, 作为 ArrayList 内部类
    (4)ArrayList 是实现聚合接口 List 的子类,实现了 iterator()
    (5)迭代器模式解决了 不同集合(ArrayList ,LinkedList) 统一遍历问题
  4. 具体内容
    迭代器模式

十六 观察者模式(多对一依赖)

  1. 基本介绍
    对象之间多对一依赖的一种设计方案,被依赖的对象为 Subject,依赖的对象为 Observer,Subject通知 Observer 变化
  2. 案例原理类图
    在这里插入图片描述
    说明:
    (1)奶站/气象局:Subject
    (2)用户/第三方网站:Observer
    Subject:登记注册、移除和通知
    ① registerObserver 注册
    ② removeObserver 移除
    ③ notifyObservers() 通知所有的注册的用户,根据不同需求,可以是更新数据,让用户来取,也可能是实施推送,看具体需求定
    Observer:接收输入
  3. JDK的Observable类使用了观察者模式
    在这里插入图片描述
    在这里插入图片描述

模式角色分析
① Obvervable:等价于前面的Subject,是类,不是接口,类中已经实现了核心的方法 ,即管理 Observer 的方法 add… delete … notify…
② Observer 等价于前面的 Observer, 有 update
③ Observable 和 Observer 的使用方法和前面讲过的一样,只是 Observable 是类,通过继承来实现观察者模式
4. 具体内容
观察者模式

十七 中介者模式(中介者对象拥有对象map集合)

  1. 基本介绍
    用一个中介对象来封装一系列的对象交互。中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互
  2. 原理类图
    在这里插入图片描述
    说明:
    (1)Mediator 就是抽象中介者,定义了同事对象到中介者对象的接口
    (2)Colleague 是抽象同事类
    (3)ConcreteMediator 具体的中介者对象, 实现抽象方法, 他需要知道所有的具体的同事类,即以一个集合来管理HashMap,并接受某个同事对象消息,完成相应的任务
    (4)ConcreteColleague 具体的同事类,会有很多, 每个同事只知道自己的行为,而不了解其他同事类的行为(方法),但是他们都依赖中介者对象
  3. 具体内容
    中介者模式

十八 备忘录模式(守护者保存状态)

  1. 基本介绍
    在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态
  2. 原理类图
    在这里插入图片描述
    说明:
    (1)originator : 对象(需要保存状态的对象)
    (2)Memento : 备忘录对象,负责保存好记录,即 Originator 内部状态
    (3)Caretaker: 守护者对象,负责保存多个备忘录对象, 使用集合管理,提高效率
    (4)如果希望保存多个 originator 对象的不同时间的状态,也可以,只需要要 HashMap <String, 集合>
  3. 具体内容
    备忘录模式

十九 解释器模式(解释表达式)

  1. 基本介绍
    是指给定一个语言(表达式),定义它的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子(表达式)
  2. 原理类图
    在这里插入图片描述
    说明:
    (1)Context: 是环境角色,含有解释器之外的全局信息
    (2)AbstractExpression: 抽象表达式, 声明一个抽象的解释操作,这个方法为抽象语法树中所有的节点所共享
    (3)TerminalExpression: 为终结符表达式, 实现与文法中的终结符相关的解释操作
    (4)NonTermialExpression: 为非终结符表达式,为文法中的非终结符实现解释操作
  3. Spring框架中的SpelExpressionParser使用了解释器模式
    在这里插入图片描述
    在这里插入图片描述
  4. 具体内容
    解释器模式

二十 状态模式(状态对应行为)

  1. 基本介绍
    它主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题。状态和行为是一一对应的,状态之间可以相互转换
  2. 原理类图
    在这里插入图片描述
    说明:
    (1)State 是抽象状态角色,定义一个接口封装与 Context 的一个特点接口相关行为
    (2)Context 类为环境角色, 用于维护 State 实例,这个实例定义当前状态
    (3)ConcreteState 具体的状态角色,每个子类实现一个与 Context 的一个状态相关行为
  3. 具体内容
    状态模式

二十一 策略模式(变与不变,策略接口组,客户主体)

  1. 基本介绍
    (1)策略模式(Strategy Pattern)中,定义算法族(策略组),分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户
    (2)这算法体现了几个设计原则,第一、把变化的代码从不变的代码中分离出来;第二、针对接口编程而不是具体类(定义了策略接口);第三、多用组合/聚合,少用继承(客户通过组合方式使用策略)
  2. 原理类图
    客户 context 有成员变量 strategy 或者其他的策略接口
    ,至于需要使用到哪个策略,我们可以在构造器中指定
    在这里插入图片描述
  3. JDK的Arrays的Comparator使用了策略模式
    在这里插入图片描述
  4. 具体内容
    策略模式

二十二 职责链模式(职责对象链)

  1. 基本介绍
    为请求创建了一个接收者对象的链。这种模式对请求的发送者和接收者进行解耦。
    职责链模式通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
  2. 原理类图
    在这里插入图片描述
    (1)Request , 含有很多属性,表示一个请求
    (2)Handler : 抽象的处理者, 定义了一个处理请求的接口, 同时含有另外 Handler
    (3)ConcreteHandlerA , B 是具体的处理者, 处理它自己负责的请求, 可以访问它的后继者(即下一个处理者), 如果可以处理当前请求,则处理,否则就将该请求交个 后继者去处理,从而形成一个职责链
  3. SpringMVC的HandlerExecutionChain使用了职责链模式
    在这里插入图片描述
    说明:
    (1)springmvc 请求的流程图中,执行了 拦截器相关方法 interceptor.preHandler 等等
    (2)在处理 SpringMvc 请求时,使用到职责链模式还使用到适配器模式
    (3)HandlerExecutionChain 主要负责的是请求拦截器的执行和请求处理,但是他本身不处理请求,只是将请求分配给链上注册处理器执行,这是职责链实现方式,减少职责链本身与处理逻辑之间的耦合,规范了处理流程
    (4)HandlerExecutionChain 维护了HandlerInterceptor 的集合, 可以向其中注册相应的拦截器.
  4. 具体内容
    职责链模式
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值