# 创建者模式

# 建造者模式

建造者模式所完成的内容就是通过将多个简单对象通过⼀步步的组装构建出⼀个复杂对象的过程。

⼯程中有三个核⼼类和⼀个测试类,核⼼类是建造者模式的具体实现。与 ifelse 实现⽅式相⽐,多出

来了两个⼆外的类。具体功能如下;

Builder ,建造者类具体的各种组装由此类实现。

DecorationPackageMenu ,是 IMenu 接⼝的实现类,主要是承载建造过程中的填充器。相当于

这是⼀套承载物料和创建者中间衔接的内容。

# 原型模式

原型模式主要解决的问题就是创建重复对象

另外原型设计模式的优点包括;便于通过克隆⽅式创建复杂对象、也可以避免᯿复做初始化操作、

不需要与类中所属的其他类耦合等。但也有⼀些缺点如果对象中包括了循环引⽤的克隆,以及类中

深度使⽤对象的克隆,都会使此模式变得异常麻烦。

终究设计模式是⼀整套的思想,在不同的场景合理的运⽤可以提升整体的架构的质量。永远不要想

着去硬凑设计模式,否则将会引起过渡设计,以及在承接业务反复变化的需求时造成浪费的开发和

维护成本。

初期是代码的优化,中期是设计模式的使⽤,后期是把控全局服务的搭建。不断的加强⾃⼰对全局

能⼒的把控,也加深⾃⼰对细节的处理。可上可下才是⼀个程序员最佳处理⽅式,选取做合适的才

是最好的选择。

# 单例模式

7种单例模式实现

  • 静态类使用
  • 懒汉模式(线程不安全)
public class Singleton_01 {

    private static Singleton_01 instance;

    private Singleton_01() {
    }

    public static Singleton_01 getInstance(){
        if (null != instance) return instance;
        return new Singleton_01();
    }

}

单例模式有⼀个特点就是不允许外部直接创建,也就是 new Singleton_01() ,因此这⾥在默认

的构造函数上添加了私有属性 private 。

⽬前此种⽅式的单例确实满⾜了懒加载,但是如果有多个访问者同时去获取对象实例你可以想象成

⼀堆⼈在抢厕所,就会造成多个同样的实例并存,从⽽没有达到单例的要求。

  • 懒汉模式(线程安全)
public class Singleton_02 {

    private static Singleton_02 instance;

    private Singleton_02() {
    }

    public static synchronized Singleton_02 getInstance(){
        if (null != instance) return instance;
        return new Singleton_02();
    }

}
  • 饿汉模式 ( 线程安全 )
public class Singleton_03 {

    private static Singleton_03 instance = new Singleton_03();

    private Singleton_03() {
    }

    public static Singleton_03 getInstance() {
        return instance;
    }

}
  • 使⽤类的内部类 ( 线程安全 )
public class Singleton_04 {

    private static class SingletonHolder {
        private static Singleton_04 instance = new Singleton_04();
    }

    private Singleton_04() {
    }

    public static Singleton_04 getInstance() {
        return SingletonHolder.instance;
    }

}
    • 使用类的静态内部类实现的单例模式,既保证了线程安全又保证了懒加载,同时不会因为枷锁的方式消耗性能
  • 主要是因为JVM虚拟机可以保证多线程并发访问的正确性,也就是一个类的构造方法在多线程环境下可以被正确加载
  • 双重锁校验(线程安全)
    • 双重锁的方式是方法级锁的优化,减少了部分获取实例的耗时
  • 同时也满足懒加载
  • CASAtomicReference( 线程安全 )
  • Effffective Java作者推荐的枚举单例 ( 线程安全 )
public enum Singleton_07 {

    INSTANCE;
    public void test(){
        System.out.println("hi~");
    }

}

约书亚·布洛克(英语:Joshua J. Bloch,1961年8⽉28⽇-),美国著名程序员。他为Java平台

设计并实作了许多的功能,曾担任Google的⾸席Java架构师(Chief Java Architect)。

Effffective Java 作者推荐使⽤枚举的⽅式解决单例模式,此种⽅式可能是平时最少⽤到的。

这种⽅式解决了最主要的;线程安全、⾃由串⾏化、单⼀实例。

# 工厂模式

# 行为模式

# 策略模式

# 简介

策略模式主要用于在运行时动态地改变算法或策略。它包含三个部分:Context(上下文),Strategy(策略)和ConcreteStrategy(具体策略)。Context持有一个Strategy类型的成员变量,在运行时可以替换成不同的ConcreteStrategy,从而实现不同的行为。策略模式的优点是增加新的策略很容易,而且符合开闭原则。

它允许在运行时动态地改变对象的行为。该模式通过将算法封装在独立的类中,并使它们可以相互替换来实现这一目标,从而实现算法的灵活性。

在策略模式中,通常会定义一个公共接口或抽象类来表示算法族,然后定义多个具体的算法类来实现该接口。

策略模式特别适用于在运行时根据不同情况选择不同的算法。

例子:优惠券的选择

# 责任链模式

责任链模式是一种行为型设计模式。它通过将请求沿着处理对象的链传递,直到有一个处理对象对请求进行处理为止,从而避免了请求发送者和接收者之间的直接耦合。

在责任链模式中,处理对象可以是一个单独的对象或者是一组对象,这些对象按照某种顺序链接在一起。每个处理对象都有机会来处理请求,并且根据需要可以把请求转发给下一个处理对象。

这种模式的主要作用是分离请求发送者和接收者之间的耦合关系,使得请求发送者无需知道哪个对象最终会处理请求。同时也可以灵活地添加、删除或调整处理对象,从而方便地改变处理请求的方式。

责任链模式通常在以下场景下使用:

  1. 多个对象可以处理同一个请求,但具体由哪个对象来处理该请求在运行时刻动态决定。
  2. 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
  3. 可以动态地增加或修改处理请求的对象,增强系统的灵活性和可扩展性。

# 命令模式

命令模式是一种行为设计模式,它将请求封装成一个对象,从而使您可以使用不同的请求、队列或日志来参数化其他对象。该模式允许您将操作请求与发出这些请求的对象解耦。

在命令模式中,客户端创建一个命令对象并设置其接收者。然后,客户端将命令传递给调用者,调用者将命令放入命令队列中。最终,命令将被执行,而不需要知道其具体细节。

在软件开发中,命令模式通常用于实现撤销和重做功能,以及实现事务机制。此外,它还可用于构建复杂的用户界面,其中命令可以关联到菜单项、按钮等 UI 元素上。

当您需要将请求分离出来,并且在不改变任何类的情况下对其进行参数化时,命令模式非常有用。例如,当您需要记录操作历史、实现事务管理、实现多级撤销和重做功能时,命令模式是一个非常好的选择。

# 中介者模式

中介者模式要解决的就是复杂功能应⽤之间的᯿复调⽤,在这中间添加⼀层中介者包装服务,对外提供

简单、通⽤、易扩展的服务能⼒。

中介者模式是一种行为型模式,它的主要作用是将多个对象之间的复杂交互关系进行解耦,从而使得这些对象能够更加灵活地相互协作。在中介者模式中,所有对象都通过中介者对象来实现彼此之间的通信,而不需要直接依赖其它对象。

中介者模式的重点是协调对象之间的通信,

# 观察者模式

# 访问者模式

访问者模式的核⼼在于同⼀个事物不同视⻆下的访问信息不同

访问者模式是一种行为型设计模式,它的核心思想是将数据结构与对其所进行的操作分离开来。访问者模式通过在被访问的对象中添加接受访问者对象的方法,使得访问者可以访问并处理这些数据结构中的元素。这样,在不改变数据结构本身的前提下,可以实现不同的操作。

访问者模式包含以下几个要素:

  1. 抽象访问者(Visitor):定义了访问者可以访问的各种元素,并且为每种元素都提供了一个访问方法。
  2. 具体访问者(Concrete Visitor):实现了抽象访问者中定义的各种访问方法,用于实现具体的操作。
  3. 抽象元素(Element):定义了一个接受访问者对象的方法 accept(),该方法接受一个访问者对象作为参数。
  4. 具体元素(Concrete Element):实现了抽象元素中定义的 accept() 方法,用于接受访问者对象,并调用访问者对象的相应方法。
  5. 对象结构(Object Structure):通常由多个具体元素组成的集合,提供了遍历元素的方法,可以让访问者访问其中的每一个元素。

适用场景:

访问者模式适用于以下情况:

  1. 对象结构中的元素类别很少改变,但需要经常添加新的操作。
  2. 需要对一个对象结构中的元素进行不同的处理,并且希望避免使用复杂的条件语句来判断每个元素的类型。
  3. 需要对一个对象结构中的元素进行多种不同的访问时,可以使用访问者模式将访问操作封装到不同的访问者中。

# 结构型模式

# 适配器模式

适配器模式的主要作⽤就是把原本不兼容的接⼝,通过适配修改做到统⼀。

在业务开发中我们会经常的需要做不同接⼝的兼容,尤其是中台服务,中台需要把各个业务线的各种类

型服务做统⼀包装,再对外提供接⼝进⾏使⽤。

适配器模式是一种结构型设计模式,它允许将一个类的接口转换成客户希望的另外一个接口。适配器模式通常用于当客户端需要使用一个已经存在的类,但其接口与客户端所需不符合的情况下。

适配器模式分为两种类型:对象适配器和类适配器对象适配器通过持有对被适配对象的引用来实现适配器功能;类适配器则采用多重继承或接口继承来实现适配器功能。

可以减少if/else语句

适配器模式的主要优点在于可以让客户端使用一些原本由于接口不匹配无法直接使用的类,并且可以让多个类共用同一个适配器来实现适配功能,提高了代码的复用性。缺点则在于适配器增加了系统的复杂度,可能会导致系统的性能略微降低

# 桥接模式

# 简介

桥接模式主要用于将抽象部分与实现部分分离,使它们可以独立地变化。它包含两个部分:Abstraction(抽象类)和Implementor(实现类)。Abstraction包含一个Implementor类型的成员变量,在运行时可以替换成不同的Implementor,从而实现不同的行为。桥接模式的优点是可以避免继承导致的类爆炸问题,降低了系统的复杂度。

# 区别:

策略模式和桥接模式的区别在于前者主要用于动态改变行为,后者主要用于将抽象和实现分离。

两种模式的区别在于它们的应用场景和解决问题的方式。策略模式通常用于解决算法的变化问题,例如在排序算法中选择不同的排序方式。而桥接模式通常用于解决抽象和实现的耦合问题,例如在图形界面中选择不同的颜色和形状。

# 组合模式

# 装饰器模式

装饰器的核⼼就是再不改原有类的基础上 给类新增功能。不改变原有类。

装饰器主要解决的是直接继承下因功能的不断横向扩展导致⼦类膨胀的问题

装饰器模式是一种设计模式,它提供了一种在运行时动态地为对象添加行为和功能的方法。使用装饰器模式,可以将一个对象包装起来,并在不修改原始对象的情况下,通过添加或修改其行为和功能改变其行为。

Spring AOP(面向切面编程)是一种编程范式,它允许在应用程序中对横切关注点进行集中处理。通过将这些关注点从核心业务逻辑中分离出来,可以实现更好的代码重用性、可维护性和可扩展性。在Spring AOP中,切面可以在运行时动态地织入到应用程序中,从而实现横切关注点的处理。

因此,装饰器模式和Spring AOP虽然都涉及到在运行时动态地修改对象行为,但它们的目的和方式是不同的。

# 享元模式

享元模式是一种常用的结构型设计模式,它通过共享对象来减少内存使用和对象创建的开销。该模式的核心思想是尽可能地重用已有的对象而不是每次都创建新的对象。

享元模式通过共享对象池的方式来管理对象,将具有相同属性的对象存储在一个池中,并且在需要使用该对象时,从池中获取并设置外部状态,避免重复创建对象。

在享元模式中,通过将可共享的状态(如颜色、大小等)抽象成一个公共类,然后将这些状态作为参数传递给具体的享元对象进行使用。该模式提供了两种类型的享元对象:内部状态和外部状态,其中内部状态可以被多个对象共享,而外部状态则必须由客户端对象传递进来。通过这种方式,我们可以在一定程度上减少系统中对象的数量,从而提高系统性能和内存利用率。

一般来说,适用于以下场景:

  1. 系统中存在大量相似对象,需要频繁创建和销毁这些对象。
  2. 对象的大部分状态都可以共享,但有一些状态需要外部定制。
  3. 需要缓存对象的场景,以便快速访问和提高系统性能。