设计模式利用Java案例

打印 上一主题 下一主题

主题 968|帖子 968|积分 2906

代码设计要有可维护性,可复用性,可扩展性,灵活性,所有要利用设计模式进行灵活设计代码
创建型

简单工厂模式(Simple Factory)

简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它通过一个工厂类来创建对象,而不是直接在客户端代码中利用 new 关键字。简单工厂模式将对象的创建逻辑会合在一个工厂类中,使客户端代码与具体实现解耦。

1. 简单工厂模式的布局

简单工厂模式包含以下角色:

  • 工厂类(Factory):负责创建对象。
  • 抽象产物类(Product):定义产物的接口或抽象类。
  • 具体产物类(Concrete Product):实现抽象产物类的具体产物。
2. UML 类图

以下是简单工厂模式的 UML 类图:
  1. +---------------------+          +---------------------+
  2. |      Factory        |          |      Product        |
  3. +---------------------+          +---------------------+
  4. | + createProduct()   | — — ————>| + use(): void       |
  5. +---------------------+          +---------------------+
  6.                                       △
  7.                                       |
  8.                                       |
  9.                       +-----------------------------+
  10.                       |                             |
  11.               +---------------------+     +---------------------+
  12.               | ConcreteProductA    |     | ConcreteProductB    |
  13.               +---------------------+     +---------------------+
  14.               | + use(): void       |     | + use(): void       |
  15.               +---------------------+     +---------------------+
复制代码
阐明


  • Factory:工厂类,负责创建具体产物。
  • Product:抽象产物类,定义产物的接口。
  • ConcreteProductAConcreteProductB:具体产物类,实现 Product 接口。
3. 代码实现

以下是一个简单的 Java 实现示例:
(1) 抽象产物类(Product)

  1. public interface Product {
  2.     void use();
  3. }
复制代码
(2) 具体产物类(ConcreteProductA 和 ConcreteProductB)

  1. public class ConcreteProductA implements Product {
  2.     @Override
  3.     public void use() {
  4.         System.out.println("Using Product A");
  5.     }
  6. }
  7. public class ConcreteProductB implements Product {
  8.     @Override
  9.     public void use() {
  10.         System.out.println("Using Product B");
  11.     }
  12. }
复制代码
(3) 工厂类(Factory)

  1. public class Factory {
  2.     public static Product createProduct(String type) {
  3.         if (type.equals("A")) {
  4.             return new ConcreteProductA();
  5.         } else if (type.equals("B")) {
  6.             return new ConcreteProductB();
  7.         } else {
  8.             throw new IllegalArgumentException("Unknown product type");
  9.         }
  10.     }
  11. }
复制代码
(4) 客户端代码

  1. public class Client {
  2.     public static void main(String[] args) {
  3.         Product productA = Factory.createProduct("A");
  4.         productA.use(); // 输出: Using Product A
  5.         Product productB = Factory.createProduct("B");
  6.         productB.use(); // 输出: Using Product B
  7.     }
  8. }
复制代码
4. 优点



  • 解耦:将对象的创建与利用分离,客户端代码无需关心具体产物的创建细节。
  • 会合管理:对象的创建逻辑会合在工厂类中,便于维护和扩展。
5. 缺点



  • 违反开闭原则:如果需要添加新的产物类型,必须修改工厂类的代码。
  • 工厂类职责过重:如果产物类型过多,工厂类的代码会变得复杂。
6. 适用场景



  • 对象的创建逻辑比较简单。
  • 客户端不需要关心对象的创建细节。
  • 产物类型较少,且不会频仍变化。
7. 总结



  • 简单工厂模式:通过工厂类会合管理对象的创建逻辑。
  • 优点:解耦、会合管理。
  • 缺点:违反开闭原则、工厂类职责过重。
  • 适用场景:对象创建逻辑简单、产物类型较少。
抽象工厂模式(Abstract Factory)

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种方式来创建一系列相干或相互依靠的对象,而无需指定它们的具体类。抽象工厂模式的焦点思想是将对象的创建与利用分离,使得系统可以在不修改代码的情况下切换整个产物族。
1. 抽象工厂模式的布局

抽象工厂模式包含以下角色:

  • 抽象工厂(Abstract Factory)

    • 定义创建一系列产物对象的接口。
    • 包含多个工厂方法,每个方法用于创建一个具体的产物对象。

  • 具体工厂(Concrete Factory)

    • 实现抽象工厂的接口,负责创建具体的产物对象。
    • 每个具体工厂对应一个产物族。

  • 抽象产物(Abstract Product)

    • 定义产物对象的接口。

  • 具体产物(Concrete Product)

    • 实现抽象产物的接口,是具体工厂创建的对象。

  • 客户端(Client)

    • 利用抽象工厂和抽象产物接口,无需关心具体的实现类。

2. 抽象工厂模式的 UML 图


3. 抽象工厂模式的实现

以下是一个简单的抽象工厂模式的代码示例:
(1) 抽象产物

  1. // 抽象产品 A
  2. interface ProductA {
  3.     void methodA();
  4. }
  5. // 抽象产品 B
  6. interface ProductB {
  7.     void methodB();
  8. }
复制代码
(2) 具体产物

  1. // 具体产品 A1
  2. class ProductA1 implements ProductA {
  3.     @Override
  4.     public void methodA() {
  5.         System.out.println("ProductA1 methodA");
  6.     }
  7. }
  8. // 具体产品 B1
  9. class ProductB1 implements ProductB {
  10.     @Override
  11.     public void methodB() {
  12.         System.out.println("ProductB1 methodB");
  13.     }
  14. }
  15. // 具体产品 A2
  16. class ProductA2 implements ProductA {
  17.     @Override
  18.     public void methodA() {
  19.         System.out.println("ProductA2 methodA");
  20.     }
  21. }
  22. // 具体产品 B2
  23. class ProductB2 implements ProductB {
  24.     @Override
  25.     public void methodB() {
  26.         System.out.println("ProductB2 methodB");
  27.     }
  28. }
复制代码
(3) 抽象工厂

  1. interface AbstractFactory {
  2.     ProductA createProductA();
  3.     ProductB createProductB();
  4. }
复制代码
(4) 具体工厂

  1. // 具体工厂 1
  2. class ConcreteFactory1 implements AbstractFactory {
  3.     @Override
  4.     public ProductA createProductA() {
  5.         return new ProductA1();
  6.     }
  7.     @Override
  8.     public ProductB createProductB() {
  9.         return new ProductB1();
  10.     }
  11. }
  12. // 具体工厂 2
  13. class ConcreteFactory2 implements AbstractFactory {
  14.     @Override
  15.     public ProductA createProductA() {
  16.         return new ProductA2();
  17.     }
  18.     @Override
  19.     public ProductB createProductB() {
  20.         return new ProductB2();
  21.     }
  22. }
复制代码
(5) 客户端

  1. public class Client {
  2.     public static void main(String[] args) {
  3.         // 使用具体工厂 1
  4.         AbstractFactory factory1 = new ConcreteFactory1();
  5.         ProductA productA1 = factory1.createProductA();
  6.         ProductB productB1 = factory1.createProductB();
  7.         productA1.methodA();
  8.         productB1.methodB();
  9.         // 使用具体工厂 2
  10.         AbstractFactory factory2 = new ConcreteFactory2();
  11.         ProductA productA2 = factory2.createProductA();
  12.         ProductB productB2 = factory2.createProductB();
  13.         productA2.methodA();
  14.         productB2.methodB();
  15.     }
  16. }
复制代码
输出
  1. ProductA1 methodA
  2. ProductB1 methodB
  3. ProductA2 methodA
  4. ProductB2 methodB
复制代码
4. 抽象工厂模式的优点


  • 解耦:将对象的创建与利用分离,客户端只需依靠抽象接口,无需关心具体实现。
  • 扩展性:可以轻松扩展新的产物族,只需增加新的具体工厂和产物类。
  • 一致性:确保创建的产物对象属于同一个产物族,制止不兼容的对象组合。
5. 抽象工厂模式的缺点


  • 复杂性:增加了系统的复杂性,需要定义多个接口和类。
  • 扩展困难:如果需要增加新的产物类型(如 ProductC),需要修改抽象工厂和所有具体工厂的接口。
6. 适用场景



  • 系统需要创建一系列相干或相互依靠的对象。
  • 系统需要支持多个产物族,并且可以在运行时切换产物族。
  • 系统需要确保创建的对象属于同一个产物族。
工厂方法模式(Factory Method)

工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它定义了一个创建对象的接口,但由子类决定实例化哪个类。工厂方法模式将对象的创建耽误到子类,使得系统可以在不修改代码的情况下扩展新的产物类型。
1. 工厂方法模式的布局

工厂方法模式包含以下角色:

  • 抽象产物(Product)

    • 定义产物对象的接口。

  • 具体产物(Concrete Product)

    • 实现抽象产物的接口,是工厂方法创建的对象。

  • 抽象工厂(Creator)

    • 定义工厂方法(Factory Method),用于创建产物对象。

  • 具体工厂(Concrete Creator)

    • 实现工厂方法,返回具体产物的实例。

2. 工厂方法模式的 UML 图


3. 工厂方法模式的实现

以下是一个简单的工厂方法模式的代码示例:
(1) 抽象产物

  1. // 抽象产品
  2. interface Product {
  3.     void method();
  4. }
复制代码
(2) 具体产物

  1. // 具体产品 A
  2. class ConcreteProductA implements Product {
  3.     @Override
  4.     public void method() {
  5.         System.out.println("ConcreteProductA method");
  6.     }
  7. }
  8. // 具体产品 B
  9. class ConcreteProductB implements Product {
  10.     @Override
  11.     public void method() {
  12.         System.out.println("ConcreteProductB method");
  13.     }
  14. }
复制代码
(3) 抽象工厂

  1. // 抽象工厂
  2. abstract class Creator {
  3.     // 工厂方法
  4.     public abstract Product factoryMethod();
  5.     // 其他方法
  6.     public void someOperation() {
  7.         Product product = factoryMethod();
  8.         product.method();
  9.     }
  10. }
复制代码
(4) 具体工厂

  1. // 具体工厂 A
  2. class ConcreteCreatorA extends Creator {
  3.     @Override
  4.     public Product factoryMethod() {
  5.         return new ConcreteProductA();
  6.     }
  7. }
  8. // 具体工厂 B
  9. class ConcreteCreatorB extends Creator {
  10.     @Override
  11.     public Product factoryMethod() {
  12.         return new ConcreteProductB();
  13.     }
  14. }
复制代码
(5) 客户端

  1. public class Client {
  2.     public static void main(String[] args) {
  3.         // 使用具体工厂 A
  4.         Creator creatorA = new ConcreteCreatorA();
  5.         creatorA.someOperation();
  6.         // 使用具体工厂 B
  7.         Creator creatorB = new ConcreteCreatorB();
  8.         creatorB.someOperation();
  9.     }
  10. }
复制代码
输出
  1. ConcreteProductA method
  2. ConcreteProductB method
复制代码
4. 工厂方法模式的优点


  • 解耦:将对象的创建与利用分离,客户端只需依靠抽象接口,无需关心具体实现。
  • 扩展性:可以轻松扩展新的产物类型,只需增加新的具体工厂和产物类。
  • 单一职责:每个具体工厂只负责创建一种产物,符合单一职责原则。
5. 工厂方法模式的缺点


  • 复杂性:增加了系统的复杂性,需要定义多个接口和类。
  • 类的数量增加:每增加一种产物类型,都需要增加一个具体工厂类。
6. 适用场景



  • 系统需要支持多种产物类型,并且可以在运行时动态切换。
  • 系统需要将对象的创建与利用分离,提高灵活性和可维护性。
  • 系统需要遵循开闭原则,支持扩展而不修改现有代码。
7. 工厂方法模式与简单工厂模式与抽象工厂模式的区别



  • 简单工厂模式:由一个工厂类负责创建所有产物对象,不符合开闭原则。
  • 工厂方法模式:将对象的创建耽误到子类,符合开闭原则。
  • 抽象工厂模式:将创建一系列相干或相互依靠的对象,符合开闭原则。
建造者模式(Builder)

建造者模式(Builder Pattern)是一种创建型设计模式,它用于将一个复杂对象的构建与其表现分离,使得同样的构建过程可以创建不同的表现。建造者模式适用于需要分步骤创建复杂对象的场景,尤其是在对象的构建过程需要多个步骤或参数时。
1. 建造者模式的布局

建造者模式包含以下角色:

  • 产物(Product)

    • 表现被构建的复杂对象。

  • 抽象建造者(Builder)

    • 定义构建产物的各个步骤的接口。

  • 具体建造者(Concrete Builder)

    • 实现抽象建造者的接口,完成产物的具体构建。

  • 指挥者(Director)

    • 负责调用建造者的方法,控制构建过程。

  • 客户端(Client)

    • 利用指挥者和建造者创建产物。

2. 建造者模式的 UML 图


3. 建造者模式的实现

以下是一个简单的建造者模式的代码示例:
(1) 产物

  1. // 产品
  2. class Product {
  3.     private String partA;
  4.     private String partB;
  5.     public void setPartA(String partA) {
  6.         this.partA = partA;
  7.     }
  8.     public void setPartB(String partB) {
  9.         this.partB = partB;
  10.     }
  11.     @Override
  12.     public String toString() {
  13.         return "Product{partA='" + partA + "', partB='" + partB + "'}";
  14.     }
  15. }
复制代码
(2) 抽象建造者

  1. // 抽象建造者
  2. interface Builder {
  3.     void buildPartA();
  4.     void buildPartB();
  5.     Product getResult();
  6. }
复制代码
(3) 具体建造者

  1. // 具体建造者
  2. class ConcreteBuilder implements Builder {
  3.     private Product product = new Product();
  4.     @Override
  5.     public void buildPartA() {
  6.         product.setPartA("PartA");
  7.     }
  8.     @Override
  9.     public void buildPartB() {
  10.         product.setPartB("PartB");
  11.     }
  12.     @Override
  13.     public Product getResult() {
  14.         return product;
  15.     }
  16. }
复制代码
(4) 指挥者

  1. // 指挥者
  2. class Director {
  3.     private Builder builder;
  4.     public Director(Builder builder) {
  5.         this.builder = builder;
  6.     }
  7.     public void construct() {
  8.         builder.buildPartA();
  9.         builder.buildPartB();
  10.     }
  11. }
复制代码
(5) 客户端

  1. public class Client {
  2.     public static void main(String[] args) {
  3.         // 创建具体建造者
  4.         Builder builder = new ConcreteBuilder();
  5.         // 创建指挥者
  6.         Director director = new Director(builder);
  7.         // 构建产品
  8.         director.construct();
  9.         // 获取产品
  10.         Product product = builder.getResult();
  11.         System.out.println(product);
  12.     }
  13. }
复制代码
输出
  1. Product{partA='PartA', partB='PartB'}
复制代码
4. 建造者模式的优点


  • 分离构建与表现:将复杂对象的构建过程与其表现分离,使得同样的构建过程可以创建不同的表现。
  • 灵活性:可以灵活地改变产物的内部表现,只需增加新的具体建造者。
  • 控制构建过程:指挥者可以精确控制产物的构建过程。
5. 建造者模式的缺点


  • 复杂性:增加了系统的复杂性,需要定义多个类。
  • 适用范围有限:适用于需要分步骤构建复杂对象的场景,对于简单对象可能显得冗余。
6. 适用场景



  • 需要创建复杂对象,且对象的构建过程需要多个步骤。
  • 需要创建的对象具有多个构成部分,且这些构成部分可以灵活组合。
  • 需要将对象的构建过程与其表现分离。
7. 建造者模式与工厂模式的区别



  • 工厂模式:关注于创建单个对象,适用于创建过程简单的场景。
  • 建造者模式:关注于分步骤创建复杂对象,适用于创建过程复杂的场景。
原型模式(Prototype)

原型模式(Prototype Pattern)是一种创建型设计模式,它通过复制现有对象来创建新对象,而不是通过实例化类。原型模式适用于创建成本较高的对象,大概需要动态配置对象的场景。
1. 原型模式的布局

原型模式包含以下角色:

  • 抽象原型(Prototype)

    • 定义克隆方法的接口。

  • 具体原型(Concrete Prototype)

    • 实现抽象原型的接口,完成对象的克隆。

  • 客户端(Client)

    • 利用原型对象创建新对象。

2. 原型模式的 UML 图


3. 原型模式的实现

以下是一个简单的原型模式的代码示例:
(1) 抽象原型

  1. // 抽象原型
  2. interface Prototype {
  3.     Prototype clone();
  4. }
复制代码
(2) 具体原型

  1. // 具体原型
  2. class ConcretePrototype implements Prototype {
  3.     private String field;
  4.     public ConcretePrototype(String field) {
  5.         this.field = field;
  6.     }
  7.     @Override
  8.     public Prototype clone() {
  9.         return new ConcretePrototype(this.field);
  10.     }
  11.     @Override
  12.     public String toString() {
  13.         return "ConcretePrototype{field='" + field + "'}";
  14.     }
  15. }
复制代码
(3) 客户端

  1. public class Client {
  2.     public static void main(String[] args) {
  3.         // 创建原型对象
  4.         Prototype prototype = new ConcretePrototype("Original");
  5.         // 克隆对象
  6.         Prototype clone = prototype.clone();
  7.         System.out.println("Prototype: " + prototype);
  8.         System.out.println("Clone: " + clone);
  9.     }
  10. }
复制代码
输出
  1. Prototype: ConcretePrototype{field='Original'}
  2. Clone: ConcretePrototype{field='Original'}
复制代码
4. 原型模式的优点


  • 性能优化:通过复制现有对象创建新对象,制止了重复的初始化操作,提高了性能。
  • 动态配置:可以在运行时动态配置对象的属性。
  • 简化创建过程:对于创建成本较高的对象,原型模式可以简化创建过程。
5. 原型模式的缺点


  • 深拷贝与浅拷贝:需要正确处理对象的深拷贝和浅拷贝问题。
  • 复杂性:对于包含循环引用的对象,克隆过程可能变得复杂。
6. 适用场景



  • 需要创建的对象成本较高(如需要复杂的初始化过程)。
  • 需要动态配置对象的属性。
  • 需要制止重复创建相似对象。
7. 深拷贝与浅拷贝



  • 浅拷贝:只复制对象的基本类型字段和引用类型字段的引用,不复制引用类型字段指向的对象。
  • 深拷贝:复制对象的所有字段,包括引用类型字段指向的对象。
示例:深拷贝

  1. class ConcretePrototype implements Prototype, Cloneable {
  2.     private String field;
  3.     private List<String> list;
  4.     public ConcretePrototype(String field, List<String> list) {
  5.         this.field = field;
  6.         this.list = list;
  7.     }
  8.     @Override
  9.     public Prototype clone() {
  10.         try {
  11.             ConcretePrototype clone = (ConcretePrototype) super.clone();
  12.             clone.list = new ArrayList<>(this.list); // 深拷贝
  13.             return clone;
  14.         } catch (CloneNotSupportedException e) {
  15.             throw new RuntimeException(e);
  16.         }
  17.     }
  18.     @Override
  19.     public String toString() {
  20.         return "ConcretePrototype{field='" + field + "', list=" + list + "}";
  21.     }
  22. }
复制代码
8. 原型模式与工厂模式的区别



  • 工厂模式:通过工厂方法创建新对象,适用于创建过程简单的场景。
  • 原型模式:通过复制现有对象创建新对象,适用于创建成本较高的场景。
单例模式(Singleton)

单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点。单例模式适用于需要全局唯一对象的场景,如配置管理、线程池、日志纪录等。
1. 单例模式的布局

单例模式包含以下角色:

  • 单例类(Singleton)

    • 定义获取唯一实例的方法。
    • 确保类只有一个实例。

  • 客户端(Client)

    • 利用单例类的唯一实例。

2. 单例模式的 UML 图


3. 单例模式的实现

以下是几种常见的单例模式实现方式:
(1) 懒汉式(线程不安全)

  1. class Singleton {
  2.     private static Singleton instance;
  3.     private Singleton() {}
  4.     public static Singleton getInstance() {
  5.         if (instance == null) {
  6.             instance = new Singleton();
  7.         }
  8.         return instance;
  9.     }
  10. }
复制代码
缺点:线程不安全,多个线程可能同时创建多个实例。
(2) 懒汉式(线程安全)

  1. class Singleton {
  2.     private static Singleton instance;
  3.     private Singleton() {}
  4.     public static synchronized Singleton getInstance() {
  5.         if (instance == null) {
  6.             instance = new Singleton();
  7.         }
  8.         return instance;
  9.     }
  10. }
复制代码
缺点:每次调用 getInstance() 都会加锁,性能较差。
(3) 双重查抄锁(Double-Checked Locking)

  1. class Singleton {
  2.     private static volatile Singleton instance;
  3.     private Singleton() {}
  4.     public static Singleton getInstance() {
  5.         if (instance == null) {
  6.             synchronized (Singleton.class) {
  7.                 if (instance == null) {
  8.                     instance = new Singleton();
  9.                 }
  10.             }
  11.         }
  12.         return instance;
  13.     }
  14. }
复制代码
优点:线程安全,且只有在第一次创建实例时加锁,性能较好。
(4) 静态内部类

  1. class Singleton {
  2.     private Singleton() {}
  3.     private static class SingletonHolder {
  4.         private static final Singleton INSTANCE = new Singleton();
  5.     }
  6.     public static Singleton getInstance() {
  7.         return SingletonHolder.INSTANCE;
  8.     }
  9. }
复制代码
优点:线程安全,且耽误加载(Lazy Initialization)。
(5) 摆列

  1. enum Singleton {
  2.     INSTANCE;
  3.     public void doSomething() {
  4.         System.out.println("Singleton is doing something.
  5. ");
  6.     }
  7. }
复制代码
优点:线程安全,且防止反射攻击。
4. 单例模式的优点


  • 全局唯一:确保一个类只有一个实例。
  • 节流资源:制止重复创建对象,节流系统资源。
  • 全局访问点:提供一个全局访问点,方便管理。
5. 单例模式的缺点


  • 扩展性差:单例类通常难以扩展。
  • 测试困难:单例类的全局状态可能导致测试困难。
  • 违反单一职责原则:单例类通常承担了创建和管理实例的职责。
6. 适用场景



  • 需要全局唯一对象的场景,如配置管理、线程池、日志纪录等。
  • 需要频仍创建和销毁对象的场景,利用单例模式可以节流资源。
7. 单例模式的注意事项


  • 线程安全:确保单例类在多线程环境下正常工作。
  • 耽误加载:根据需求选择是否耽误加载实例。
  • 防止反射攻击:通过摆列或私有构造方法防止反射创建新实例。
8. 示例代码

以下是利用双重查抄锁实现的单例模式:
  1. public class Singleton {
  2.     private static volatile Singleton instance;
  3.     private Singleton() {
  4.         // 防止反射创建新实例
  5.         if (instance != null) {
  6.             throw new RuntimeException("Use getInstance() method to get the single instance.");
  7.         }
  8.     }
  9.     public static Singleton getInstance() {
  10.         if (instance == null) {
  11.             synchronized (Singleton.class) {
  12.                 if (instance == null) {
  13.                     instance = new Singleton();
  14.                 }
  15.             }
  16.         }
  17.         return instance;
  18.     }
  19.     public void doSomething() {
  20.         System.out.println("Singleton is doing something.
  21. ");
  22.     }
  23. }
复制代码
客户端代码
  1. public class Client {
  2.     public static void main(String[] args) {
  3.         Singleton instance = Singleton.getInstance();
  4.         instance.doSomething();
  5.     }
  6. }
复制代码
输出
  1. Singleton is doing something.
复制代码
布局型设计模式

适配器模式

适配器模式(Adapter Pattern)是一种布局型设计模式,它允许不兼容的接口之间进行协作。适配器模式通过将一个类的接口转换成客户端期望的另一个接口,使得原本由于接口不兼容而无法一起工作的类可以一起工作。
1. 适配器模式的布局

适配器模式包含以下角色:

  • 目标接口(Target)

    • 客户端期望的接口。

  • 适配者(Adaptee)

    • 需要被适配的类。

  • 适配器(Adapter)

    • 实现目标接口,并包装适配者对象,使其可以大概与客户端协作。

  • 客户端(Client)

    • 利用目标接口与适配器交互。

2. 适配器模式的 UML 图


3. 适配器模式的实现

以下是一个简单的适配器模式的代码示例:
(1) 目标接口

  1. // 目标接口
  2. interface Target {
  3.     void request();
  4. }
复制代码
(2) 适配者

  1. // 适配者
  2. class Adaptee {
  3.     public void specificRequest() {
  4.         System.out.println("Adaptee specificRequest
  5. ");
  6.     }
  7. }
复制代码
(3) 适配器

  1. // 适配器
  2. class Adapter implements Target {
  3.     private Adaptee adaptee;
  4.     public Adapter(Adaptee adaptee) {
  5.         this.adaptee = adaptee;
  6.     }
  7.     @Override
  8.     public void request() {
  9.         adaptee.specificRequest();
  10.     }
  11. }
复制代码
(4) 客户端

  1. public class Client {
  2.     public static void main(String[] args) {
  3.         // 创建适配者
  4.         Adaptee adaptee = new Adaptee();
  5.         // 创建适配器
  6.         Target target = new Adapter(adaptee);
  7.         // 使用目标接口
  8.         target.request();
  9.     }
  10. }
复制代码
输出
  1. Adaptee specificRequest
复制代码
4. 适配器模式的优点


  • 解耦:将客户端与适配者解耦,客户端只需依靠目标接口。
  • 复用性:可以复用现有的类,而无需修改其代码。
  • 灵活性:可以动态地切换适配器,支持多种适配者。
5. 适配器模式的缺点


  • 复杂性:增加了系统的复杂性,需要定义额外的适配器类。
  • 性能开销:适配器模式可能引入额外的性能开销。
6. 适用场景



  • 需要利用现有的类,但其接口与系统不兼容。
  • 需要创建一个可以复用的类,该类可以与其他不相干的类协作。
  • 需要统一多个类的接口。
7. 适配器模式的类型


  • 类适配器

    • 利用继承实现适配器。
    • 适配器继承适配者,并实现目标接口。
    示例
    1. class Adapter extends Adaptee implements Target {
    2.     @Override
    3.     public void request() {
    4.         specificRequest();
    5.     }
    6. }
    复制代码

  • 对象适配器

    • 利用组合实现适配器。
    • 适配器包装适配者对象,并实现目标接口。
    示例
    1. class Adapter implements Target {
    2.     private Adaptee adaptee;
    3.     public Adapter(Adaptee adaptee) {
    4.         this.adaptee = adaptee;
    5.     }
    6.     @Override
    7.     public void request() {
    8.         adaptee.specificRequest();
    9.     }
    10. }
    复制代码

8. 示例代码

以下是利用对象适配器实现的适配器模式:
  1. // 目标接口
  2. interface Target {
  3.     void request();
  4. }
  5. // 适配者
  6. class Adaptee {
  7.     public void specificRequest() {
  8.         System.out.println("Adaptee specificRequest
  9. ");
  10.     }
  11. }
  12. // 适配器
  13. class Adapter implements Target {
  14.     private Adaptee adaptee;
  15.     public Adapter(Adaptee adaptee) {
  16.         this.adaptee = adaptee;
  17.     }
  18.     @Override
  19.     public void request() {
  20.         adaptee.specificRequest();
  21.     }
  22. }
  23. // 客户端public class Client {
  24.     public static void main(String[] args) {
  25.         // 创建适配者
  26.         Adaptee adaptee = new Adaptee();
  27.         // 创建适配器
  28.         Target target = new Adapter(adaptee);
  29.         // 使用目标接口
  30.         target.request();
  31.     }
  32. }
复制代码
输出
  1. Adaptee specificRequest
复制代码
桥接模式(Bridge)

桥接模式(Bridge Pattern)是一种布局型设计模式,它将抽象部分与实现部分分离,使它们可以独立变化。桥接模式通过组合代替继承,解决了多层继承带来的复杂性。
1. 桥接模式的布局

桥接模式包含以下角色:

  • 抽象部分(Abstraction)

    • 定义抽象接口,并包含一个对实现部分的引用。

  • 扩展抽象部分(Refined Abstraction)

    • 扩展抽象部分,增加额外的功能。

  • 实现部分(Implementor)

    • 定义实现部分的接口。

  • 具体实现部分(Concrete Implementor)

    • 实现实现部分的接口。

  • 客户端(Client)

    • 利用抽象部分与实现部分交互。

2. 桥接模式的 UML 图


3. 桥接模式的实现

以下是一个简单的桥接模式的代码示例:
(1) 实现部分

  1. // 实现部分
  2. interface Implementor {
  3.     void operationImpl();
  4. }
复制代码
(2) 具体实现部分

  1. // 具体实现部分 A
  2. class ConcreteImplementorA implements Implementor {
  3.     @Override
  4.     public void operationImpl() {
  5.         System.out.println("ConcreteImplementorA operationImpl");
  6.     }
  7. }
  8. // 具体实现部分 B
  9. class ConcreteImplementorB implements Implementor {
  10.     @Override
  11.     public void operationImpl() {
  12.         System.out.println("ConcreteImplementorB operationImpl");
  13.     }
  14. }
复制代码
(3) 抽象部分

  1. // 抽象部分
  2. abstract class Abstraction {
  3.     protected Implementor implementor;
  4.     public Abstraction(Implementor implementor) {
  5.         this.implementor = implementor;
  6.     }
  7.     public abstract void operation();
  8. }
复制代码
(4) 扩展抽象部分

  1. // 扩展抽象部分
  2. class RefinedAbstraction extends Abstraction {
  3.     public RefinedAbstraction(Implementor implementor) {
  4.         super(implementor);
  5.     }
  6.     @Override
  7.     public void operation() {
  8.         System.out.println("RefinedAbstraction operation");
  9.         implementor.operationImpl();
  10.     }
  11. }
复制代码
(5) 客户端

  1. public class Client {
  2.     public static void main(String[] args) {
  3.         // 使用具体实现部分 A
  4.         Implementor implementorA = new ConcreteImplementorA();
  5.         Abstraction abstractionA = new RefinedAbstraction(implementorA);
  6.         abstractionA.operation();
  7.         // 使用具体实现部分 B
  8.         Implementor implementorB = new ConcreteImplementorB();
  9.         Abstraction abstractionB = new RefinedAbstraction(implementorB);
  10.         abstractionB.operation();
  11.     }
  12. }
复制代码
输出
  1. RefinedAbstraction operation
  2. ConcreteImplementorA operationImpl
  3. RefinedAbstraction operation
  4. ConcreteImplementorB operationImpl
复制代码
4. 桥接模式的优点


  • 分离抽象与实现:将抽象部分与实现部分分离,使它们可以独立变化。
  • 扩展性:可以独立扩展抽象部分和实现部分,无需修改现有代码。
  • 减少子类:制止了多层继承带来的复杂性。
5. 桥接模式的缺点


  • 复杂性:增加了系统的复杂性,需要定义多个接口和类。
  • 设计难度:需要正确识别抽象部分和实现部分,设计难度较高。
6. 适用场景



  • 需要将抽象部分与实现部分分离,使它们可以独立变化。
  • 需要制止多层继承带来的复杂性。
  • 需要在运行时动态切换实现部分。
7. 桥接模式与适配器模式的区别



  • 适配器模式:用于解决接口不兼容的问题,通常在系统设计完成后利用。
  • 桥接模式:用于将抽象部分与实现部分分离,通常在系统设计阶段利用。
组合模式(Composite)

组合模式(Composite Pattern)是一种布局型设计模式,它允许你将对象组合成树形布局以表现“部分-整体”的条理布局。组合模式使得客户端可以统一处理单个对象和组合对象。
1. 组合模式的布局

组合模式包含以下角色:

  • 组件(Component)

    • 定义组合中所有对象的通用接口。

  • 叶子节点(Leaf)

    • 表现组合中的叶子对象,没有子节点。

  • 复合节点(Composite)

    • 表现组合中的复合对象,包含子节点。

  • 客户端(Client)

    • 利用组件接口与组合布局交互。

2. 组合模式的 UML 图


3. 组合模式的实现

以下是一个简单的组合模式的代码示例:
(1) 组件

  1. // 组件
  2. interface Component {
  3.     void operation();
  4. }
复制代码
(2) 叶子节点

  1. // 叶子节点
  2. class Leaf implements Component {
  3.     private String name;
  4.     public Leaf(String name) {
  5.         this.name = name;
  6.     }
  7.     @Override
  8.     public void operation() {
  9.         System.out.println("Leaf " + name + " operation");
  10.     }
  11. }
复制代码
(3) 复合节点

  1. // 复合节点
  2. class Composite implements Component {
  3.     private List<Component> children = new ArrayList<>();
  4.     public void add(Component component) {
  5.         children.add(component);
  6.     }
  7.     public void remove(Component component) {
  8.         children.remove(component);
  9.     }
  10.     public Component getChild(int index) {
  11.         return children.get(index);
  12.     }
  13.     @Override
  14.     public void operation() {
  15.         System.out.println("Composite operation");
  16.         for (Component component : children) {
  17.             component.operation();
  18.         }
  19.     }
  20. }
复制代码
(4) 客户端

  1. public class Client {
  2.     public static void main(String[] args) {
  3.         // 创建叶子节点
  4.         Component leaf1 = new Leaf("Leaf1");
  5.         Component leaf2 = new Leaf("Leaf2");
  6.         Component leaf3 = new Leaf("Leaf3");
  7.         // 创建复合节点
  8.         Composite composite = new Composite();
  9.         composite.add(leaf1);
  10.         composite.add(leaf2);
  11.         // 创建另一个复合节点
  12.         Composite composite2 = new Composite();
  13.         composite2.add(leaf3);
  14.         composite2.add(composite);
  15.         // 使用组件
  16.         composite2.operation();
  17.     }
  18. }
复制代码
输出
  1. Composite operation
  2. Leaf Leaf3 operation
  3. Composite operation
  4. Leaf Leaf1 operation
  5. Leaf Leaf2 operation
复制代码

4. 组合模式的优点


  • 统一处理:客户端可以统一处理单个对象和组合对象。
  • 灵活性:可以动态地添加或删除组件。
  • 简化代码:减少了客户端代码的复杂性。
5. 组合模式的缺点


  • 设计复杂性:需要正确识别组件、叶子节点和复合节点,设计难度较高。
  • 类型查抄:客户端可能需要查抄组件的类型,增加了代码的复杂性。
6. 适用场景



  • 需要表现“部分-整体”的条理布局。
  • 需要统一处理单个对象和组合对象。
  • 需要动态地添加或删除组件。
装饰模式(Decorator)

装饰模式(Decorator Pattern)是一种布局型设计模式,它允许你通过将对象放入包含行为的特殊封装对象中来为原对象动态添加新的行为。装饰模式通过组合代替继承,提供了更灵活的方式来扩展对象的功能。
1. 装饰模式的布局

装饰模式包含以下角色:

  • 组件(Component)

    • 定义对象的接口,可以动态地添加行为。

  • 具体组件(Concrete Component)

    • 实现组件接口,是被装饰的原始对象。

  • 装饰器(Decorator)

    • 包含一个对组件对象的引用,并实现组件接口。

  • 具体装饰器(Concrete Decorator)

    • 扩展装饰器,添加新的行为。

  • 客户端(Client)

    • 利用组件接口与装饰后的对象交互。

2. 装饰模式的 UML 图


3. 装饰模式的实现

以下是一个简单的装饰模式的代码示例:
(1) 组件

  1. // 组件
  2. interface Component {
  3.     void operation();
  4. }
复制代码
(2) 具体组件

  1. // 具体组件
  2. class ConcreteComponent implements Component {
  3.     @Override
  4.     public void operation() {
  5.         System.out.println("ConcreteComponent operation");
  6.     }
  7. }
复制代码
(3) 装饰器

  1. // 装饰器
  2. abstract class Decorator implements Component {
  3.     protected Component component;
  4.     public Decorator(Component component) {
  5.         this.component = component;
  6.     }
  7.     @Override
  8.     public void operation() {
  9.         component.operation();
  10.     }
  11. }
复制代码
(4) 具体装饰器

  1. // 具体装饰器 A
  2. class ConcreteDecoratorA extends Decorator {
  3.     public ConcreteDecoratorA(Component component) {
  4.         super(component);
  5.     }
  6.     @Override
  7.     public void operation() {
  8.         super.operation();
  9.         addedBehavior();
  10.     }
  11.     private void addedBehavior() {
  12.         System.out.println("ConcreteDecoratorA addedBehavior");
  13.     }
  14. }
  15. // 具体装饰器 B
  16. class ConcreteDecoratorB extends Decorator {
  17.     public ConcreteDecoratorB(Component component) {
  18.         super(component);
  19.     }
  20.     @Override
  21.     public void operation() {
  22.         super.operation();
  23.         addedBehavior();
  24.     }
  25.     private void addedBehavior() {
  26.         System.out.println("ConcreteDecoratorB addedBehavior");
  27.     }
  28. }
复制代码
(5) 客户端

  1. public class Client {
  2.     public static void main(String[] args) {
  3.         // 创建具体组件
  4.         Component component = new ConcreteComponent();
  5.         // 使用具体装饰器 A 装饰组件
  6.         Component decoratedComponentA = new ConcreteDecoratorA(component);
  7.         decoratedComponentA.operation();
  8.         // 使用具体装饰器 B 装饰组件
  9.         Component decoratedComponentB = new ConcreteDecoratorB(component);
  10.         decoratedComponentB.operation();
  11.         // 使用多个装饰器装饰组件
  12.         Component decoratedComponentAB = new ConcreteDecoratorB(new ConcreteDecoratorA(component));
  13.         decoratedComponentAB.operation();
  14.     }
  15. }
复制代码
输出
  1. ConcreteComponent operation
  2. ConcreteDecoratorA addedBehavior
  3. ConcreteComponent operation
  4. ConcreteDecoratorB addedBehavior
  5. ConcreteComponent operation
  6. ConcreteDecoratorA addedBehavior
  7. ConcreteDecoratorB addedBehavior
复制代码
4. 装饰模式的优点


  • 动态扩展:可以在运行时动态地添加或删除功能。
  • 单一职责:每个装饰器只负责一个功能,符合单一职责原则。
  • 灵活性:可以组合多个装饰器,提供更灵活的功能扩展。
5. 装饰模式的缺点


  • 复杂性:增加了系统的复杂性,需要定义多个装饰器类。
  • 调试困难:由于装饰器可以嵌套,调试可能变得困难。
6. 适用场景



  • 需要动态地添加或删除功能。
  • 需要扩展对象的功能,但不盼望利用继承。
  • 需要组合多个功能。
7. 装饰模式与继承的区别



  • 继承:静态地扩展对象的功能,编译时确定。
  • 装饰模式:动态地扩展对象的功能,运行时确定。
8. 组合模式与装饰器模式的区别



  • 组合模式:用于表现“部分-整体”的条理布局,客户端可以统一处理单个对象和组合对象。
  • 装饰器模式:用于动态地添加功能,客户端可以透明地利用装饰后的对象。
表面模式(Facade)

表面模式(Facade Pattern)是一种布局型设计模式,它提供了一个统一的接口,用于访问子系统中的一组接口。表面模式通过定义一个高层接口,简化了客户端与子系统之间的交互。
1. 表面模式的布局

表面模式包含以下角色:

  • 表面(Facade)

    • 提供一个统一的接口,用于访问子系统中的一组接口。

  • 子系统(Subsystem)

    • 包含一组类,实现子系统的功能。

  • 客户端(Client)

    • 利用表面接口与子系统交互。

2. 表面模式的 UML 图


3. 表面模式的实现

以下是一个简单的表面模式的代码示例:
(1) 子系统

  1. // 子系统 A
  2. class SubsystemA {
  3.     public void operationA() {
  4.         System.out.println("SubsystemA operationA");
  5.     }
  6. }
  7. // 子系统 B
  8. class SubsystemB {
  9.     public void operationB() {
  10.         System.out.println("SubsystemB operationB");
  11.     }
  12. }
  13. // 子系统 C
  14. class SubsystemC {
  15.     public void operationC() {
  16.         System.out.println("SubsystemC operationC");
  17.     }
  18. }
复制代码
(2) 表面

  1. // 外观
  2. class Facade {
  3.     private SubsystemA subsystemA;
  4.     private SubsystemB subsystemB;
  5.     private SubsystemC subsystemC;
  6.     public Facade() {
  7.         subsystemA = new SubsystemA();
  8.         subsystemB = new SubsystemB();
  9.         subsystemC = new SubsystemC();
  10.     }
  11.     public void operation() {
  12.         subsystemA.operationA();
  13.         subsystemB.operationB();
  14.         subsystemC.operationC();
  15.     }
  16. }
复制代码
(3) 客户端

  1. public class Client {
  2.     public static void main(String[] args) {
  3.         // 创建外观
  4.         Facade facade = new Facade();
  5.         // 使用外观
  6.         facade.operation();
  7.     }
  8. }
复制代码
输出
  1. SubsystemA operationA
  2. SubsystemB operationB
  3. SubsystemC operationC
复制代码
4. 表面模式的优点


  • 简化接口:提供了一个统一的接口,简化了客户端与子系统的交互。
  • 解耦:将客户端与子系统解耦,客户端只需依靠表面接口。
  • 易于利用:客户端无需了解子系统的复杂性,只需调用表面接口。
5. 表面模式的缺点


  • 不符合开闭原则:如果需要修改子系统的功能,可能需要修改表面类。
  • 灵活性差:表面类可能变得复杂,难以扩展。
6. 适用场景



  • 需要简化客户端与复杂子系统的交互。
  • 需要将客户端与子系统解耦。
  • 需要为子系统提供一个统一的接口。
7. 表面模式与适配器模式的区别



  • 表面模式:用于简化客户端与子系统的交互,提供一个统一的接口。
  • 适配器模式:用于解决接口不兼容的问题,通常在系统设计完成后利用。
享元模式(Flyweight)

享元模式(Flyweight Pattern)是一种布局型设计模式,它通过共享对象来减少内存利用和提高性能。享元模式适用于需要创建大量相似对象的场景,通过共享这些对象的内部状态,减少内存占用。
1. 享元模式的布局

享元模式包含以下角色:

  • 享元(Flyweight)

    • 定义共享对象的接口。

  • 具体享元(Concrete Flyweight)

    • 实现享元接口,包含内部状态。

  • 享元工厂(Flyweight Factory)

    • 创建和管理享元对象,确保共享。

  • 客户端(Client)

    • 利用享元对象,维护外部状态。

2. 享元模式的 UML 图


3. 享元模式的实现

以下是一个简单的享元模式的代码示例:
(1) 享元

  1. // 享元
  2. interface Flyweight {
  3.     void operation(String extrinsicState);
  4. }
复制代码
(2) 具体享元

  1. // 具体享元
  2. class ConcreteFlyweight implements Flyweight {
  3.     private String intrinsicState;
  4.     public ConcreteFlyweight(String intrinsicState) {
  5.         this.intrinsicState = intrinsicState;
  6.     }
  7.     @Override
  8.     public void operation(String extrinsicState) {
  9.         System.out.println("Intrinsic State: " + intrinsicState);
  10.         System.out.println("Extrinsic State: " + extrinsicState);
  11.     }
  12. }
复制代码
(3) 享元工厂

  1. // 享元工厂
  2. class FlyweightFactory {
  3.     private Map<String, Flyweight> flyweights = new HashMap<>();
  4.     public Flyweight getFlyweight(String key) {
  5.         if (!flyweights.containsKey(key)) {
  6.             flyweights.put(key, new ConcreteFlyweight(key));
  7.         }
  8.         return flyweights.get(key);
  9.     }
  10. }
复制代码
(4) 客户端

  1. public class Client {
  2.     public static void main(String[] args) {
  3.         // 创建享元工厂
  4.         FlyweightFactory factory = new FlyweightFactory();
  5.         // 获取享元对象
  6.         Flyweight flyweight1 = factory.getFlyweight("A");
  7.         Flyweight flyweight2 = factory.getFlyweight("B");
  8.         Flyweight flyweight3 = factory.getFlyweight("A");
  9.         // 使用享元对象
  10.         flyweight1.operation("State1");
  11.         flyweight2.operation("State2");
  12.         flyweight3.operation("State3");
  13.         // 检查享元对象是否共享
  14.         System.out.println("flyweight1 == flyweight3: " + (flyweight1 == flyweight3));
  15.     }
  16. }
复制代码
输出
  1. Intrinsic State: A
  2. Extrinsic State: State1
  3. Intrinsic State: B
  4. Extrinsic State: State2
  5. Intrinsic State: A
  6. Extrinsic State: State3
  7. flyweight1 == flyweight3: true
复制代码
4. 享元模式的优点


  • 减少内存利用:通过共享对象,减少内存占用。
  • 提高性能:减少了对象的创建和销毁,提高了性能。
  • 灵活性:可以动态地添加或删除享元对象。
5. 享元模式的缺点


  • 复杂性:增加了系统的复杂性,需要区分内部状态和外部状态。
  • 线程安全:在多线程环境下,需要确保享元对象的线程安全。
6. 适用场景



  • 需要创建大量相似对象。
  • 对象的大部分状态可以外部化。
  • 需要减少内存利用和提高性能。
7. 享元模式与单例模式的区别



  • 单例模式:确保一个类只有一个实例,适用于全局唯一对象的场景。
  • 享元模式:通过共享对象减少内存利用,适用于需要创建大量相似对象的场景。
代理模式(Proxy)

代理模式(Proxy Pattern)是一种布局型设计模式,它提供了一个代理对象,用于控制对另一个对象的访问。代理模式通常用于耽误加载、访问控制、日志纪录等场景。
1. 代理模式的布局

代理模式包含以下角色:

  • 抽象主题(Subject)

    • 定义真实主题和代理对象的共同接口。

  • 真实主题(Real Subject)

    • 实现抽象主题接口,是代理对象所代表的真实对象。

  • 代理(Proxy)

    • 实现抽象主题接口,并包含一个对真实主题的引用,用于控制对真实主题的访问。

  • 客户端(Client)

    • 利用抽象主题接口与代理对象交互。

2. 代理模式的 UML 图


3. 代理模式的实现

以下是一个简单的代理模式的代码示例:
(1) 抽象主题

  1. // 抽象主题
  2. interface Subject {
  3.     void request();
  4. }
复制代码
(2) 真实主题

  1. // 真实主题
  2. class RealSubject implements Subject {
  3.     @Override
  4.     public void request() {
  5.         System.out.println("RealSubject request");
  6.     }
  7. }
复制代码
(3) 代理

  1. // 代理
  2. class Proxy implements Subject {
  3.     private RealSubject realSubject;
  4.     @Override
  5.     public void request() {
  6.         if (realSubject == null) {
  7.             realSubject = new RealSubject();
  8.         }
  9.         preRequest();
  10.         realSubject.request();
  11.         postRequest();
  12.     }
  13.     private void preRequest() {
  14.         System.out.println("Proxy preRequest");
  15.     }
  16.     private void postRequest() {
  17.         System.out.println("Proxy postRequest");
  18.     }
  19. }
复制代码
(4) 客户端

  1. public class Client {
  2.     public static void main(String[] args) {
  3.         // 创建代理
  4.         Subject proxy = new Proxy();
  5.         // 使用代理
  6.         proxy.request();
  7.     }
  8. }
复制代码
输出
  1. Proxy preRequest
  2. RealSubject request
  3. Proxy postRequest
复制代码
4. 代理模式的优点


  • 控制访问:可以在访问真实主题之前或之后执行额外的操作。
  • 耽误加载:可以耽误真实主题的创建,直到真正需要时。
  • 解耦:将客户端与真实主题解耦,客户端只需依靠抽象主题接口。
5. 代理模式的缺点


  • 复杂性:增加了系统的复杂性,需要定义额外的代理类。
  • 性能开销:代理模式可能引入额外的性能开销。
6. 适用场景



  • 需要控制对真实对象的访问。
  • 需要耽误加载真实对象。
  • 需要在访问真实对象之前或之后执行额外的操作。
7. 代理模式的类型


  • 长途代理

    • 用于在不同的所在空间中代表对象。

  • 捏造代理

    • 用于耽误加载真实对象。

  • 保护代理

    • 用于控制对真实对象的访问权限。

  • 智能引用代理

    • 用于在访问真实对象时执行额外的操作,如日志纪录、引用计数等。

行为设计模式

计谋模式

计谋模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互更换。计谋模式让算法的变化独立于利用它的客户端。
1. 计谋模式的布局

计谋模式包含以下角色:

  • 计谋接口(Strategy):定义算法的接口。
  • 具体计谋类(Concrete Strategy):实现计谋接口的具体算法。
  • 上下文类(Context):持有一个计谋对象的引用,并通过计谋接口调用具体算法。
2. UML 类图


阐明


  • Strategy:计谋接口,定义算法的接口。
  • ConcreteStrategyAConcreteStrategyB:具体计谋类,实现 Strategy 接口。
  • Context:上下文类,持有一个计谋对象的引用,并通过计谋接口调用具体算法。
3. 代码实现

以下是一个简单的 Java 实现示例:
(1) 计谋接口(Strategy)

  1. public interface Strategy {
  2.     void execute();
  3. }
复制代码
(2) 具体计谋类(ConcreteStrategyA 和 ConcreteStrategyB)

  1. public class ConcreteStrategyA implements Strategy {
  2.     @Override
  3.     public void execute() {
  4.         System.out.println("Executing Strategy A");
  5.     }
  6. }
  7. public class ConcreteStrategyB implements Strategy {
  8.     @Override
  9.     public void execute() {
  10.         System.out.println("Executing Strategy B");
  11.     }
  12. }
复制代码
(3) 上下文类(Context)

  1. public class Context {
  2.     private Strategy strategy;
  3.     public void setStrategy(Strategy strategy) {
  4.         this.strategy = strategy;
  5.     }
  6.     public void executeStrategy() {
  7.         if (strategy != null) {
  8.             strategy.execute();
  9.         } else {
  10.             System.out.println("No strategy set");
  11.         }
  12.     }
  13. }
复制代码
(4) 客户端代码

  1. public class Client {
  2.     public static void main(String[] args) {
  3.         Context context = new Context();
  4.         // 使用策略 A
  5.         context.setStrategy(new ConcreteStrategyA());
  6.         context.executeStrategy(); // 输出: Executing Strategy A
  7.         // 使用策略 B
  8.         context.setStrategy(new ConcreteStrategyB());
  9.         context.executeStrategy(); // 输出: Executing Strategy B
  10.     }
  11. }
复制代码
4. 优点



  • 开闭原则:可以在不修改上下文类的情况下添加新的计谋。
  • 制止条件语句:通过计谋模式可以制止利用大量的条件语句。
  • 算法复用:不同的上下文可以共享相同的计谋。
5. 缺点



  • 客户端必须了解计谋:客户端需要知道所有计谋类,并选择符合的计谋。
  • 计谋类增多:如果计谋类过多,系统会变得复杂。
6. 适用场景



  • 需要在运行时动态选择算法。
  • 有多个相似的类,仅在行为上有所不同。
  • 需要制止利用大量的条件语句。
7. 总结



  • 计谋模式:将算法封装在独立的计谋类中,使它们可以相互更换。
  • 优点:开闭原则、制止条件语句、算法复用。
  • 缺点:客户端必须了解计谋、计谋类增多。
  • 适用场景:动态选择算法、制止条件语句。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

用多少眼泪才能让你相信

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表