当前位置: 首页 > news >正文

软件设计师知识点总结:面向对象技术(设计模式)

 

目录

 

一、设计模式的要素

 1.定义

2.设计模式一般有以下4个基本要素。

简单工厂模式

定义:

示例图:

代码实现:

二、创建型设计模式

1. 抽象工厂模式(Abstract Factory)

2. 生成器模式(Builder)(套餐)

3. 工厂方法模式(Factory Method)

4. 原型模式(Prototype)

5. 单例模式(Singleton)

三、结构型设计模式

1. 适配器模式(Adapter)(Usb-Type-c)

2. 桥接模式(Bridge)(产品-产品颜色)

3. 组合模式(Composite)(文件-文件夹)

4. 装饰器模式(Decorator)(学生)

5. 外观模式(Facade)(网站)

6. 享元模式(Flyweight)(黑白五子棋)

7. 代理模式(Proxy)(中介)

四、行为型设计模式

1. 责任链模式(Chain of Responsibility)(请假、链表)

2. 命令模式(Command)(电视开关机)

3. 解释器模式(Interpreter)(解释)

4. 迭代器模式(Iterator)(顺序访问,不暴露内部)

5. 中介者模式(Mediator)(组长-员工)

6.备忘录模式(Memento)

7. 观察者模式(Observer)(作者-粉丝)

8. 状态模式(State)(快递状态、贩卖机)

9. 策略模式(Strategy)(算法)

10. 模板方法模式(Template Method)

11. 访问者模式(Visitor)

五、总结


一、设计模式的要素

 1.定义

  设计模式的核心在于提供了相关问题的解决方案,使得人们可以更简单方便地复用成功的设计和体系结构。

2.设计模式一般有以下4个基本要素。

  • 模式名称
  • 问题
  • 解决方案
  • 效果


简单工厂模式

定义:

属于创建型设计模式,但不属于23种设计模式之一。

示例图:

代码实现:
public class SimpleFactory {public static void main(String[] args) {Product productA = Factory.createProduct("A");productA.info();Product productB = Factory.createProduct("B");}
}abstract class Product {public abstract void info();
}class Factory {public static Product createProduct(String type) {Product product = null;switch (type) {case "A":product = new ProductA();break;case "B":product = new ProductB();break;default:System.out.println("没有 " + type + " 类型的产品!");break;}return product;}
}class ProductA extends Product {@Overridepublic void info() {System.out.println("产品的信息:A");}
}class ProductB extends Product {@Overridepublic void info() {System.out.println("产品的信息:B");}
}

二、创建型设计模式

1. 抽象工厂模式(Abstract Factory)

  • 意图:提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定定它们具体的类。
  • 结构
    • 抽象工厂(Abstract Factory):声明创建一系列产品的接口。
    • 具体工厂(Concrete Factory):实现抽象工厂接口,负责创建特定系列的产品。
    • 抽象产品(Abstract Product):定义产品的接口。
    • 具体产品(Concrete Product):实现抽象产品接口,由具体工厂创建。
    • 客户端(Client):仅抽象工厂和抽象产品接口交互,不依赖具体工厂和产品。
  • 适用性
    • 系统需独立于产品的创建、构成和表示。
    • 系统需由多个产品系列中的一个来配置。
    • 强调一系列相关产品的联合使用,需保证产品兼容性。
    • 希望提供产品类库,且只展示接口而非实现。
  • 示例图:

  • 代码实现:
    public class AbstractFactory {public static void main(String[] args) {Factory factory1 = new Factory1();ProductA productA = factory1.createProductA();productA.info();Factory factory2 = new Factory2();ProductB productB = factory2.createProductB();productB.info();}
    }interface Factory {public ProductA createProductA();public ProductB createProductB();
    }class Factory1 implements Factory {@Overridepublic ProductA createProductA() {return new ProductA1();}@Overridepublic ProductB createProductB() {return new ProductB1();}
    }class Factory2 implements Factory {@Overridepublic ProductA createProductA() {return new ProductA2();}@Overridepublic ProductB createProductB() {return new ProductB2();}
    }interface ProductA {public void info();
    }class ProductA1 implements ProductA {@Overridepublic void info() {System.out.println("产品的信息:A1");}
    }class ProductA2 implements ProductA {@Overridepublic void info() {System.out.println("产品的信息:A2");}
    }interface ProductB {public void info();
    }class ProductB1 implements ProductB {@Overridepublic void info() {System.out.println("产品的信息:B1");}
    }class ProductB2 implements ProductB {@Overridepublic void info() {System.out.println("产品的信息:B2");}
    }

2. 生成器模式(Builder)(套餐)

  • 意图:将复杂对象的构建与表示分离,使同样的构建过程可创建不同的表示。
  • 结构
    • 构建器(Builder):声明创建产品各部件的抽象接口。
    • 具体构建器(Concrete Builder):实现构建器接口,构造并装配产品部件,定义并跟踪产品表示,提供获取产品的接口。
    • 指挥者(Director):调用构建器的部件构造方法,按特定顺序构建复杂对象。
    • 产品(Product):被构建的复杂对象,具体构建器定义其组装过程。
  • 适用性
    • 创建复杂对象的算法独立于组成对象的部件及装配方式。
    • 构建过程需允许被构建对象有不同表示(如同一数据可生成不同格式文档)。
  • 示例图:

  • 代码实现
    import java.util.*;public class Main {public static void main(String[] args) {Director director = new Director();Builder builder1 = new Builder1();director.Construct(builder1);Product product1 = builder1.getResult();product1.show();Builder builder2 = new Builder2();director.Construct(builder2);Product product2 = builder2.getResult();product2.show();}
    }class Director {public void Construct(Builder builder) {builder.BuildPart();}
    }abstract class Builder {public abstract void BuildPart();public abstract Product getResult();
    }class Builder1 extends Builder {Product product = new Product();@Overridepublic void BuildPart() {product.Add("A");product.Add("B");product.Add("C");product.Add("D");product.Add("E");product.Add("F");}@Overridepublic Product getResult() {return product;}
    }class Builder2 extends Builder {Product product = new Product();@Overridepublic void BuildPart() {product.Add("A");product.Add("B");product.Add("C");}@Overridepublic Product getResult() {return product;}
    }class Product {List<String> parts = new ArrayList<String>();public void Add(String part) {parts.add(part);}public void show() {System.out.print("产品的组成:");for (String s : parts)System.out.print(s + " ");System.out.print("\n");}
    }

3. 工厂方法模式(Factory Method)

  • 意图:定义创建对象的接口,让子类决定实例化哪一个类,使实例化延迟到子类
  • 结构
    • 产品(Product):定义工厂方法所创建对象的接口
    • 具体产品(Concrete Product):实现产品接口。
    • 创建者(Creator):声明工厂方法,返回产品类型对象,可包含依赖工厂方法的默认实现。
    • 具体创建者(Concrete Creator):重写工厂方法,返回具体产品实例。
  • 适用性
    • 类不知道它所必须创建的对象的类。
    • 类希望由子类指定它所创建的对象
    • 父类将创建对象的职责委托给子类,子类通过重写工厂方法实现该职责。
  • 示例图:

  • 代码实现
    public class FactoryMethod {public static void main(String[] args) {Factory factoryA = new FactoryA();// 父类 对象名 = new 子类();Product productA = factoryA.createProduct();// Product productA = new ProductA();productA.info();Factory factoryB = new FactoryB();Product productB = factoryB.createProduct();productB.info();}
    }// class Factory
    interface Factory {public Product createProduct();
    }class FactoryA implements Factory {@Overridepublic Product createProduct() {return new ProductA();}
    }class FactoryB implements Factory {@Overridepublic Product createProduct() {return new ProductB();}
    }// abstract class Product
    interface Product {// public abstract void info();public void info();
    }// class ProductA extends Product
    class ProductA implements Product {@Overridepublic void info() {System.out.println("产品的信息:A");}
    }// class ProductB extends Product
    class ProductB implements Product {@Overridepublic void info() {System.out.println("产品的信息:B");}
    }

4. 原型模式(Prototype)

  • 意图:用原型实例指定创建对象的种类,通过复制该原型创建新对象
  • 结构
    • 原型(Prototype):声明克隆自身的接口。
    • 具体原型(Concrete Prototype):实现克隆接口,复制自身创建新实例。
    • 客户端(Client):通过请求原型克隆自身创建新对象。
  • 适用性
    • 类实例化需要消耗过多资源(如数据、时间),克隆更高效。
    • 需避免创建与产品类层次平行的工厂类层次。
    • 动态生成对象,且对象类型繁多,难以用工厂模式管理。
    • 实例化的类是在运行时动态指定的
  • 示例图:

  • 代码实现
    public class Main {public static void main(String[] args) {Product product1 = new Product(2022, 5.28);System.out.println(product1.getId() + " " + product1.getPrice());// Product product2 = new Product(2022, 5.28);Product product2 = (Product) product1.Clone();System.out.println(product2.getId() + " " + product2.getPrice());Product product3 = (Product) product1.Clone();System.out.println(product3.getId() + " " + product3.getPrice());}
    }interface Prototype {public Object Clone();
    }class Product implements Prototype {private int id;private double price;public Product() {}public Product(int id, double price) {this.id = id;this.price = price;}public int getId() {return id;}public double getPrice() {return price;}@Overridepublic Object Clone() {Product object = new Product();object.id = this.id;object.price = this.price;return object;}
    }

5. 单例模式(Singleton)

  • 意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
  • 结构
    • 单例(Singleton):包含一个私有构造函数(防止外部实例化),一个静态私有实例和一个静态公有方法(返回该实例,确保唯一)。
  • 适用性
    • 类只能有一个实例,且需被全局访问(如配置管理器、日志管理器)。
    • 唯一实例需通过子类化扩展,且客户端无需修改代码即可使用扩展后的实例
  • 示例图:
  • 代码实现:
public class SingletonPattern {public static void main(String[] args) {// Singleton singleton1 = new Singleton();Singleton singleton1 = Singleton.getInstance();Singleton singleton2 = Singleton.getInstance();Singleton singleton3 = Singleton.getInstance();System.out.println(singleton1.getNumber() + " " + singleton2.getNumber() + " " + singleton3.getNumber());singleton1.setNumber(528);System.out.println(singleton1.getNumber() + " " + singleton2.getNumber() + " " + singleton3.getNumber());}
}class Singleton {private int number = 2022;public void setNumber(int number) {this.number = number;}public int getNumber() {return number;}private static Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}
}

三、结构型设计模式

1. 适配器模式(Adapter)(Usb-Type-c)

  • 意图将一个类的接口转换成客户希望的另一个接口,使接口不兼容的类可协同工作。
  • 结构
    • 目标(Target):定义客户端使用的接口。
    • 适配者(Adaptee):需要适配的现有接口。
    • 适配器(Adapter):实现目标接口,内部引用适配者,将目标接口方法转换为适配者的相应方法。
  • 适用性
    • 想使用已有类,但接口与需求不符。
    • 需创建可复用类,与不相关或不可预见的类(接口可能不同)协同工作。
    • (对象适配器)需适配一个类及其子类,可复用适配者的子类。
  • 示例图:

  • 代码实现:
    public class AdapterPattern {public static void main(String[] args) {USB usb = new Adapter();usb.Request();}
    }class USB {public void Request() {System.out.println("USB数据线");}
    }class Adapter extends USB {private TypeC typeC = new TypeC();@Overridepublic void Request() {typeC.SpecificRequest();}
    }class TypeC {public void SpecificRequest() {System.out.println("Type-C数据线");}
    }

2. 桥接模式(Bridge)(产品-产品颜色)

  • 意图:将抽象部分与实现部分分离,使两者可独立变化
  • 结构
    • 抽象(Abstraction):定义抽象接口,包含对实现部分的引用。
    • 扩展抽象(Refined Abstraction):扩展抽象接口,实现更具体的功能。
    • 实现(Implementor):声明实现部分的接口,不依赖抽象部分。
    • 具体实现(Concrete Implementor):实现实现者接口,提供具体实现。
  • 适用性
    • 不希望抽象与实现有固定绑定关系(如抽象类与实现类可独立扩展)。
    • 抽象与实现都需通过子类扩展(如新增抽象功能和新增实现方式)。
    • 实现部分的修改不应影响客户端(如更换底层库不改变上层调用)。
    • 需在多个对象间共享实现,但客户端不能知道共享细节。
  • 示例图:

  • 代码实现
    public class BridgePattern {public static void main(String[] args) {Product productA1 = new ProductA();Product productA2 = new ProductA();Color red = new Red();productA1.setName("产品A1");productA1.setColor(red);productA1.Operation();Blue blue = new Blue();productA2.setName("产品A2");productA2.setColor(blue);productA2.Operation();}
    }abstract class Product {private String name;protected Color color;public void setName(String name) {this.name = name;}public String getName() {return name;}public void setColor(Color color) {this.color = color;}public abstract void Operation();
    }class ProductA extends Product {@Overridepublic void Operation() {color.OperationImp(this.getName());}
    }interface Color {public void OperationImp(String name);
    }class Red implements Color {@Overridepublic void OperationImp(String name) {System.out.println(name + ":红色");}
    }class Blue implements Color {@Overridepublic void OperationImp(String name) {System.out.println(name + ":蓝色");}
    }

3. 组合模式(Composite)(文件-文件夹)

  • 意图:将对象组合成树形结构表示 “部分 - 整体” 层次,使客户端对单个对象和组合对象的使用具有一致性。
  • 结构
    • 组件(Component):声明组合中所有对象的接口,包含管理子组件的默认方法(如添加、删除)。
    • 叶节点(Leaf):组合中的叶对象,无子类,实现组件接口的具体方法。
    • 组合节点(Composite):包含子组件,实现组件接口,管理子组件并委托子组件处理操作。
  • 适用性
    • 需表示对象的部分 - 整体层次结构(如文件系统、组织架构)。
    • 希望客户端忽略单个对象与组合对象的区别,统一使用它们的接口。
  • 示例图:

  • 代码实现
import java.util.*;public class CompositePattern {public static void main(String[] args) {// 父类名 对象名 = new 子类名();AbstractFile root = new Folder("root");AbstractFile folderA = new Folder("folderA");AbstractFile folderB = new Folder("folderB");AbstractFile fileC = new File("fileC");AbstractFile fileD = new File("fileD");AbstractFile fileE = new File("fileE");root.Add(folderA);root.Add(folderB);root.Add(fileC);folderA.Add(fileD);folderA.Add(fileE);print(root);}static void print(AbstractFile file) {file.printName();List<AbstractFile> childrenList = file.getChildren();if (childrenList == null) return;// for (对象类型 对象名 : 遍历对象)for (AbstractFile children : childrenList) {// children.printName();print(children);}}
}abstract class AbstractFile {protected String name;public void printName() {System.out.println(name);}public abstract boolean Add(AbstractFile file);public abstract boolean Remove(AbstractFile file);public abstract List<AbstractFile> getChildren();
}class Folder extends AbstractFile {private List<AbstractFile> childrenList = new ArrayList<AbstractFile>();public Folder(String name) {this.name = name;}@Overridepublic boolean Add(AbstractFile file) {return childrenList.add(file);}@Overridepublic boolean Remove(AbstractFile file) {return childrenList.remove(file);}@Overridepublic List<AbstractFile> getChildren() {return childrenList;}
}class File extends AbstractFile {public File(String name) {this.name = name;}@Overridepublic boolean Add(AbstractFile file) {return false;}@Overridepublic boolean Remove(AbstractFile file) {return false;}@Overridepublic List<AbstractFile> getChildren() {return null;}
}

4. 装饰器模式(Decorator)(学生)

  • 意图动态地给对象添加额外职责,比子类扩展更灵活。
  • 结构
    • 组件(Component):定义对象接口,可动态添加职责。
    • 具体组件(Concrete Component):实现组件接口,是被装饰的原始对象。
    • 装饰器(Decorator):实现组件接口,包含对组件的引用,委托组件执行操作,可在委托前后添加新功能。
    • 具体装饰器(Concrete Decorator):扩展装饰器,添加具体职责。
  • 适用性
    • 需动态、透明地给对象添加职责(如给商品动态添加服务)。
    • 需添加可撤销的职责(如动态移除装饰器)。
    • 不能通过子类扩展(因子类数量随职责组合呈爆炸性增长)。
  • 示例图:

  • 代码实现:
public class DecoratorPattern {public static void main(String[] args) {Person zhangsan = new Student("张三");zhangsan = new DecoratorA(zhangsan);zhangsan = new DecoratorB(zhangsan);zhangsan.Operation();System.out.println("\n=====我是分割线=====");// 对象链Person lisi = new DecoratorB(new DecoratorA(new Student("李四")));}
}abstract class Decorator extends Person {protected Person person;
}class DecoratorA extends Decorator {public DecoratorA(Person person) {this.person = person;}@Overridepublic void Operation() { // 职责person.Operation(); // 原本的职责System.out.print("写作业 ");}
}class DecoratorB extends Decorator {public DecoratorB(Person person) {this.person = person;}@Overridepublic void Operation() { // 职责person.Operation(); // 原本的职责System.out.print("考试 ");}
}abstract class Person {protected String name;public abstract void Operation(); // 职责
}class Student extends Person {public Student(String name) {this.name = name;}@Overridepublic void Operation() {System.out.print(name + "的职责:学习 ");}
}

5. 外观模式(Facade)(网站)

  • 意图为子系统中的一组接口提供统一高层接口,简化子系统使用。
  • 结构
    • 外观(Facade):了解子系统的所有接口,为客户端提供统一接口,将客户端请求转发给子系统相应对象。
    • 子系统类(Subsystem Classes):实现子系统功能,处理外观转发的请求,不感知外观存在。
  • 适用性
    • 需为复杂子系统提供简单接口(如简化 API 供新手使用)。
    • 客户端与子系统多个模块存在依赖,需降低耦合
    • 需构建层次化子系统,定义每层入口点(如分层架构中的层间接口)。
  • 示例图:

  • 代码实现:
    public class FacadePattern {public static void main(String[] args) {Facade facade = new Facade();facade.methodA();facade.methodB();facade.methodC();}
    }class Facade {SubSystemOne subSystemOne;SubSystemTwo subSystemTwo;SubSystemThree subSystemThree;public Facade() {subSystemOne = new SubSystemOne();subSystemTwo = new SubSystemTwo();subSystemThree = new SubSystemThree();}public void methodA() {subSystemOne.methodOne();}public void methodB() {subSystemTwo.methodTwo();}public void methodC() {subSystemThree.methodThree();}
    }class SubSystemOne {public void methodOne() {System.out.println("执行子系统一的功能");}
    }class SubSystemTwo {public void methodTwo() {System.out.println("执行子系统二的功能");}
    }class SubSystemThree {public void methodThree() {System.out.println("执行子系统三的功能");}
    }

6. 享元模式(Flyweight)(黑白五子棋)

  • 意图:运用共享技术有效支持大量细粒度对象
  • 结构
    • 享元(Flyweight):声明供享元对象的接口,可接收并作用于外部状态。
    • 具体享元(Concrete Flyweight):实现享元接口,存储内部状态(可共享),不存储外部状态(需从客户端传入)。
    • 非共享具体享元(Unshared Concrete Flyweight):无需共享的享元子类。
    • 享元工厂(Flyweight Factory):创建并管理享元对象,确保合理共享(如相同内部状态的享元只创建一个)。
    • 客户端(Client):维护享元的外部状态,向享元工厂请求享元对象。
  • 适用性
    • 应用使用大量对象,造成存储开销过大。
    • 对象大部分状态可变为外部状态(如棋子的位置、字体的大小)。
    • 移除外部状态后,可通过少量共享对象取代大量重复对象。
    • 需维护一个享元池,且该池的开销小于共享带来的收益。
  • 示例图:

  • 代码实现:
    import java.util.*;public class FlyWeightPattern {public static void main(String[] args) {ShapeFactory factory = new ShapeFactory();Random random = new Random();String[] colors = {"red", "blue", "green", "white", "black"};for (int i = 1; i <= 100; i++) {int x = random.nextInt(colors.length); // [0 ~ 4]Shape shape = factory.getShape(colors[x]);System.out.print("第" + i + "个圆:");shape.draw(random.nextInt(2022), random.nextInt(528));}}
    }class ShapeFactory {private Map<String, Shape> map = new HashMap<String, Shape>();public Shape getShape(String key) {if (!map.containsKey(key)) {map.put(key, new Circle(key));System.out.println("create color:" + key + " circle");}return map.get(key);}
    }abstract class Shape {protected String color;public abstract void draw(int x, int y);
    }class Circle extends Shape {public Circle(String color) {this.color = color;}@Overridepublic void draw(int x, int y) {System.out.println("draw a color:" + color + " circle x:" + x + " y:" + y);}
    }

7. 代理模式(Proxy)(中介)

  • 意图为其他对象提供代理以控制对该对象的访问
  • 结构
    • 抽象主题(Subject):声明真实主题和代理的共同接口。
    • 真实主题(Real Subject):实现抽象主题,是代理所代表的真实对象。
    • 代理(Proxy):实现抽象主题,包含对真实主题的引用,控制对真实主题的访问,可在访问前后添加额外操作。
  • 适用性
    • 远程代理:为不同地址空间的对象提供本地代表(如 RPC 代理)。
    • 虚拟代理:按需创建开销大的对象(如延迟加载大图片)。
    • 保护代理:控制对真实对象的访问权限(如权限验证)。
    • 智能引用:访问对象时执行附加操作(如引用计数、自动释放资源)。
  • 示例图:

  • 代码实现:
    public class ProxyPattern {public static void main(String[] args) {RealSubject realSubject = new RealSubject();Proxy proxy = new Proxy(realSubject);proxy.buy();}
    }interface Subject {public void buy();
    }class Proxy implements Subject {protected RealSubject realSubject;public Proxy(RealSubject realSubject) {this.realSubject = realSubject;}@Overridepublic void buy() {System.out.println("办理购买前的手续");realSubject.buy(); // 付钱System.out.println("办理购买后的手续");}
    }class RealSubject implements Subject {@Overridepublic void buy() {System.out.println("付钱");}
    }

    四、行为型设计模式

1. 责任链模式(Chain of Responsibility)(请假、链表)

  • 意图使多个对象都有机会处理请求,避免请求发送者与接收者耦合,将对象连成链,请求沿链传递直到被处理。
  • 结构
    • 处理者(Handler):定义处理请求的接口,包含对下一个处理者的引用。
    • 具体处理者(Concrete Handler):实现处理者接口,判断能否处理请求,若能则处理,否则转发给下一个处理者。
    • 客户端(Client):向链中第一个处理者发送请求。
  • 适用性
    • 多个对象可处理请求,且处理者需动态确定。
    • 不明确请求接收者,需解耦发送者与接收者。
    • 可处理请求的对象集合需动态调整(如动态添加 / 移除处理节点)。
  • 示例图:

2. 命令模式(Command)(电视开关机)

  • 代码实现:
    public class ChainOfResponsibilityPattern {public static void main(String[] args) {Handler fudaoyuan = new FuDaoYuan();Handler yuanzhang = new YuanZhang();Handler xiaozhang = new XiaoZhang();fudaoyuan.setNext(yuanzhang);yuanzhang.setNext(xiaozhang);fudaoyuan.HandlerRequest(31);}
    }abstract class Handler {protected Handler next;public void setNext(Handler next) {this.next = next;}public abstract void HandlerRequest(int request);
    }class FuDaoYuan extends Handler { // <= 7 审批@Overridepublic void HandlerRequest(int request) {if (request <= 7) {System.out.println("辅导员审批通过");} else {if (next != null) {next.HandlerRequest(request);} else {System.out.println("无法审批");}}}
    }class YuanZhang extends Handler { // <= 15 审批@Overridepublic void HandlerRequest(int request) {if (request <= 15) {System.out.println("院长审批通过");} else {if (next != null) {next.HandlerRequest(request);} else {System.out.println("无法审批");}}}
    }class XiaoZhang extends Handler { // <= 30 审批@Overridepublic void HandlerRequest(int request) {if (request <= 30) {System.out.println("校长审批通过");} else {if (next != null) {next.HandlerRequest(request);} else {System.out.println("无法审批");}}}
    }
  • 意图将请求封装为对象,使可用不同请求参数化客户端,支持请求排队、日志记录及撤销。
  • 结构
    • 命令(Command):声明执行操作的接口。
    • 具体命令(Concrete Command):实现命令接口,绑定接收者,调用接收者的操作。
    • 客户端(Client):创建具体命令对象,设置其接收者。
    • 调用者(Invoker):存储命令对象,调用命令的执行方法。
    • 接收者(Receiver):知道如何执行请求相关操作,是实际业务逻辑的实现者。
  • 适用性
    • 需抽象待执行动作以参数化对象(如用命令表示不同操作)。
    • 需在不同时刻指定、排列和执行请求(如任务队列)。
    • 需支持撤销、重做操作(如文本编辑器的撤销功能)。
    • 需记录请求日志,以便系统崩溃后恢复(如事务日志)。
  • 示例图:

代码实现:

public class CommandPattern {public static void main(String[] args) {Tv tv = new Tv(); // 接收者 对象 电视机Command onCommand = new OnCommand(tv); // 命令对象 开机命令Command offCommand = new OffCommand(tv); // 命令对象 关机命令Invoker invoker = new Invoker(); // 请求者invoker.setCommand(onCommand); // 给请求者设置 开机 命令invoker.call(); // 请求者去请求命令System.out.println("========================================");invoker.setCommand(offCommand); // 给请求者设置 关机命令invoker.call(); // 请求者去请求命令}
}class Invoker { // 请求者private Command command; // 命令public void setCommand(Command command) { // 设置请求者 的 请求的命令this.command = command;}public void call() { // 调用command.Execute();}
}interface Command { // 命令接口public void Execute(); // 执行命令
}class OnCommand implements Command { // 开机命令private Tv tv;public OnCommand(Tv tv) {this.tv = tv;}@Overridepublic void Execute() {tv.OnAction();}
}class OffCommand implements Command { // 关机命令private Tv tv;public OffCommand(Tv tv) {this.tv = tv;}@Overridepublic void Execute() {tv.OffAction();}
}class Tv { // 接收者 电视机public void OnAction() { // 开机行为System.out.println("电视机开机了...");}public void OffAction() { // 关机行为System.out.println("电视机关机了...");}
}

3. 解释器模式(Interpreter)(解释)

  • 意图:给定语言,定义其文法表示,并定义解释器用该表示解释语言句子。
  • 结构
    • 抽象表达式(Abstract Expression):声明解释操作的接口,包含一个解释方法。
    • 终结符表达式(Terminal Expression):实现抽象表达式,对应文法中的终结符,直接处理输入。
    • 非终结符表达式(Nonterminal Expression):实现抽象表达式,对应文法中的非终结符,包含对其他表达式的引用。
    • 上下文(Context):存储解释器之外的全局信息。
    • 客户端(Client):构建表示特定句子的抽象语法树(由终结符和非终结符表达式组成),调用解释方法。
  • 适用性
    • 语言文法简单(复杂文法建议用语法分析器生成工具)。
    • 需解释执行的句子数量有限(大量句子会导致解释器效率低)。
    • 需扩展语言文法(新增表达式类即可扩展)。

  • 示例图:

代码实现:

import java.util.*;public class InterpreterPattern {public static void main(String[] args) {Context context = new Context();context.check("A区的开发人员");context.check("B区的调试人员");context.check("C区的测试人员");System.out.println("==========");context.check("D区的程序员");context.check("D区的测试员");context.check("A区的程序员");}
}class Context {private String[] regions = {"A区", "B区", "C区"};private String[] persons = {"开发人员", "测试人员", "调试人员"};private NonterminalExprssion nonterminal;public Context() {TerminalExpression region = new TerminalExpression(regions);TerminalExpression person = new TerminalExpression(persons);nonterminal = new NonterminalExprssion(region, person);}public void check(String info) {boolean bool = nonterminal.Interpret(info);if (bool) {System.out.println("识别成功");} else {System.out.println("识别失败");}}
}interface Expression {public boolean Interpret(String info);
}class NonterminalExprssion implements Expression {private TerminalExpression region;private TerminalExpression person;public NonterminalExprssion(TerminalExpression region, TerminalExpression person) {this.region = region;this.person = person;}@Overridepublic boolean Interpret(String info) {String[] str = info.split("的");// B区的调试人员 --> str = {"B区", "调试人员"}return region.Interpret(str[0]) && person.Interpret(str[1]);}
}class TerminalExpression implements Expression {private Set<String> set = new HashSet<>();public TerminalExpression(String[] data) {// for (遍历对象类型 对象名 : 遍历对象)for (String str : data) {set.add(str);}}@Overridepublic boolean Interpret(String info) {return set.contains(info);}
}

4. 迭代器模式(Iterator)(顺序访问,不暴露内部)

  • 意图提供方法顺序访问聚合对象元素不暴露其内部表示
  • 结构
    • 迭代器(Iterator):定义访问和遍历元素的接口(如hasNext()next())。
    • 具体迭代器(Concrete Iterator):实现迭代器接口,跟踪聚合对象中的当前位置。
    • 聚合(Aggregate):声明创建迭代器的接口。
    • 具体聚合(Concrete Aggregate):实现聚合接口,返回具体迭代器实例。
  • 适用性
    • 需访问聚合对象内容但不暴露内部结构(如隐藏集合存储方式)。
    • 需为聚合对象提供多种遍历方式(如正向、反向遍历)。
    • 需为不同聚合结构提供统一遍历接口(如用相同方式遍历列表和树)。
  • 示例图:

代码实现:

import java.util.*;public class IteratorPattern {public static void main(String[] args) {BookAggregate bookAggregate = new BookAggregate();String[] books = {"数据结构", "操作系统", "计算机网络", "计算机组成原理"};double[] prices = {10.24, 20.48, 40.96, 81.92};for (int i = 0; i < 4; i++) {bookAggregate.Add(new Book(books[i], prices[i]));}Iterator bookIterator = bookAggregate.CreateIterator();while (bookIterator.hasNext()) {Book book = (Book) bookIterator.next();System.out.println(book.getName() + " " + book.getPrice());}}
}interface Iterator {public boolean hasNext();public Object next();
}class BookIterator implements Iterator {private int index;private BookAggregate bookAggregate;public BookIterator(BookAggregate bookAggregate) {this.index = 0;this.bookAggregate = bookAggregate;}@Overridepublic boolean hasNext() {if (index < bookAggregate.getSize()) {return true;} else {return false;}}@Overridepublic Object next() {Object obj = bookAggregate.get(index);index++;return obj;}
}interface Aggregate {public Iterator CreateIterator();
}class BookAggregate implements Aggregate {private List<Book> list = new ArrayList<Book>();public void Add(Book book) {list.add(book);}public Book get(int index) {return list.get(index);}public int getSize() {return list.size();}@Overridepublic Iterator CreateIterator() {return new BookIterator(this);}
}class Book {private String name;private double price;public Book(String name, double price) {this.name = name;this.price = price;}public String getName() {return name;}public double getPrice() {return price;}
}

5. 中介者模式(Mediator)(组长-员工)

  • 意图用中介对象封装对象交互,使对象无需显式引用,降低耦合,独立改变交互。
  • 结构
    • 中介者(Mediator):定义与同事对象通信的接口。
    • 具体中介者(Concrete Mediator):实现中介者接口,协调同事对象交互,了解并维护所有同事。
    • 同事(Colleague):声明与中介者通信的接口,每个同事知道自己的中介者,通过中介者与其他同事交互。
    • 具体同事(Concrete Colleague):实现同事接口,完成自身业务,需与其他同事交互时通过中介者。
  • 适用性
    • 一组对象以复杂方式相互依赖,依赖关系混乱(如网状依赖)。
    • 需定制分布在多个类中的行为,且不想生成太多子类。
    • 需减少对象间直接通信,降低耦合(如模块间通过中介通信)。
  • 示例图:

  • 代码实现:
    public class MediatorPattern {public static void main(String[] args) {ConcreteMediator mediator = new ConcreteMediator();Colleague1 colleague1 = new Colleague1(mediator);Colleague2 colleague2 = new Colleague2(mediator);mediator.setColleague1(colleague1);mediator.setColleague2(colleague2);colleague1.sendMessage("软考加油");colleague2.sendMessage("祝大家软考顺利通过!");}
    }abstract class Colleague {protected Mediator mediator;
    }class Colleague1 extends Colleague {public Colleague1(Mediator mediator) {this.mediator = mediator;}public void sendMessage(String message) {mediator.sendMessage(message, this);}public void Notify(String message) {System.out.println("同事1收到消息:" + message);}
    }class Colleague2 extends Colleague {public Colleague2(Mediator mediator) {this.mediator = mediator;}public void sendMessage(String message) {mediator.sendMessage(message, this);}public void Notify(String message) {System.out.println("同事2收到消息:" + message);}
    }abstract class Mediator {public abstract void sendMessage(String message, Colleague colleague);
    }class ConcreteMediator extends Mediator {private Colleague1 colleague1;private Colleague2 colleague2;public void setColleague1(Colleague1 colleague1) {this.colleague1 = colleague1;}public void setColleague2(Colleague2 colleague2) {this.colleague2 = colleague2;}public void sendMessage(String message, Colleague colleague) {if (colleague == colleague1) {colleague2.Notify(message); // 让同事2收到消息} else {colleague1.Notify(message); // 让同事1收到消息}}
    }

6.备忘录模式(Memento)

  • 意图不破坏封装的前提下,捕获对象内部状态并外部保存,以便后续恢复。
  • 结构
    • 原发器(Originator):创建备忘录记录自身当前状态,可使用备忘录恢复状态。
    • 备忘录(Memento):存储原发器状态,对原发器外的对象不可见(仅原发器可访问其状态)。
    • 负责人(Caretaker):负责保存备忘录,不能操作或检查备忘录内容。
  • 适用性
    • 需保存对象某时刻状态(部分或全部),以便后续恢复(如游戏存档、文档历史版本)。
    • 直接访问对象状态会暴露实现细节,破坏封装(如对象私有属性不可外部访问)。
  • 示例图:

7. 观察者模式(Observer)(作者-粉丝)

  • 代码实现:
    import java.util.*;public class MementoPattern {public static void main(String[] args) {Caretaker caretaker = new Caretaker();Originator originator = new Originator();originator.setState("1024");Memento backup1 = originator.createMemento();caretaker.addMemento(backup1);originator.setState("2048");Memento backup2 = originator.createMemento();caretaker.addMemento(backup2);originator.setState("4096");Memento backup3 = originator.createMemento();caretaker.addMemento(backup3);System.out.println(originator.getState());caretaker.showMemento();Memento memento1 = caretaker.getMemento(2);originator.setMemento(memento1);System.out.println("根据第2次备份还原之后的状态为:" + originator.getState());}
    }class Originator { // 原发器private String state;public void setState(String state) {this.state = state;}public String getState() {return state;}public Memento createMemento() {return new Memento(state);}public void setMemento(Memento memento) {state = memento.getState();}
    }class Memento { // 备忘录private String state;public Memento(String state) {this.state = state;}public String getState() {return state;}
    }class Caretaker { // 管理者private List<Memento> mementoList = new ArrayList<>();public void addMemento(Memento memento) {mementoList.add(memento);}public Memento getMemento(int index) {// 判断参数是否合法if (index >= 1 && index <= mementoList.size()) {return mementoList.get(index - 1);}return null;}public void showMemento() {int cnt = 1;// for (遍历对象类型 对象名 : 遍历对象)for (Memento memento : mementoList) {System.out.println("第" + cnt + "次备份,状态为:" + memento.getState());cnt++;}}
    }
  • 意图:定义对象间一对多依赖,当一个对象状态改变时,所有依赖它的对象自动更新。
  • 结构
    • 主题(Subject):知道其观察者,提供添加、删除观察者的接口,状态改变时通知所有观察者。
    • 具体主题(Concrete Subject):存储需要通知观察者的状态,状态改变时调用通知方法。
    • 观察者(Observer):定义更新接口,以便主题状态改变时收到通知。
    • 具体观察者(Concrete Observer):实现观察者接口,存储与主题相关的状态,收到通知时更新自身状态。
  • 适用性
    • 一个对象改变需同时改变其他对象,且不知道具体有多少对象需改变。
    • 一个对象需通知其他对象,但不能假设其他对象是谁(解耦主题与观察者)。
    • 需降低对象间耦合,使主题和观察者可独立扩展(如新增观察者无需修改主题)。
  • 示例图:

代码实现:

import java.util.*;public class ObserverPattern {public static void main(String[] args) {Subject subjectA = new ConcreteSubject("目标A");Observer observerB = new ConcreteObserver("张三", subjectA);Observer observerC = new ConcreteObserver("李四", subjectA);Observer observerD = new ConcreteObserver("王五", subjectA);subjectA.setState("更新了");System.out.println("======================================");subjectA.Detach(observerD);subjectA.setState("停更了");}
}interface Subject { // 目标public void Attach(Observer observer); // 添加观察者public void Detach(Observer observer); // 删除观察者public void Notify(); // 状态改变后 通知所有观察者public void setState(String state); // 设置状态(改变状态)public String getState(); // 获取状态
}class ConcreteSubject implements Subject {private String name;private String state;private List<Observer> observerList;public ConcreteSubject(String name) {state = "未更新";this.name = name;observerList = new ArrayList<Observer>();}public void setState(String state) {this.state = state;System.out.println(name + "的状态发生变化,变化后的状态为:" + state);Notify();}public String getState() {return state;}public void Attach(Observer observer) {observerList.add(observer);}public void Detach(Observer observer) {observerList.remove(observer);}public void Notify() {// for (遍历对象类型 对象名 : 遍历对象)for (Observer observer : observerList) {observer.update();}}
}interface Observer { // 观察者接口public void update(); // 收到通知 更新观察者的状态
}class ConcreteObserver implements Observer {private String name;private String state;private Subject subject;public ConcreteObserver(String name, Subject subject) {this.name = name;this.subject = subject;subject.Attach(this);state = subject.getState();}@Overridepublic void update() {System.out.println(name + "收到通知");state = subject.getState(); // 让当前观察者的状态 和 改变了状态之后的目标的状态保持一致System.out.println(name + "改变后的状态为:" + state);}
}

8. 状态模式(State)(快递状态、贩卖机)

  • 意图允许对象内部状态改变时改变其行为,使对象看起来好像修改了自身类
  • 结构
    • 环境(Context):定义客户端感兴趣的接口,维护一个当前状态对象,将状态相关操作委托给当前状态。
    • 状态(State):声明环境中状态相关操作的接口,可定义一个接口让状态访问环境。
    • 具体状态(Concrete State):实现状态接口,封装与环境特定状态相关的行为,可切换环境的当前状态。
  • 适用性
    • 对象行为取决于其状态,且状态需在运行时动态改变(如订单状态流转)
    • 操作含庞大的多分支条件语句,且分支依赖于对象状态(用状态类替代条件语句)。
    • 需动态添加或修改状态对应的行为(新增状态类即可)。
  • 示例图:

9. 策略模式(Strategy)(算法)

  • 代码实现:
    public class StatePattern {public static void main(String[] args) {Context context = new Context(); // count:3System.out.println(context.getState());context.Request(); // 购买一个饮料 count = 2context.Request(); // 购买一个饮料 count = 1context.Request(); // 购买一个饮料 count = 0System.out.println(context.getState());context.Request(); // 无货 等待补货 补货成功 count = 5System.out.println(context.getState());context.Request(); // 购买一个饮料 count = 4System.out.println(context.getCount());}
    }class Context { // 贩卖机private int count;private State state;public Context() {count = 3;state = new StateA();}public int getCount() {return count;}public void setCount(int count) {this.count = count;}public State getState() {return state;}public void setState(State state) {this.state = state;}public void Request() { // 购买一个饮料state.Handle(this);}}interface State {public void Handle(Context context);
    }class StateA implements State { // 有货@Overridepublic void Handle(Context context) {int count = context.getCount();if (count >= 1) {System.out.println("购买成功!");context.setCount(count - 1);if (context.getCount() == 0) {context.setState(new StateB());}} else {System.out.println("购买失败!");}}
    }class StateB implements State { // 无货@Overridepublic void Handle(Context context) {int count = context.getCount();if (count == 0) {System.out.println("购买失败!等待补货");context.setCount(5);System.out.println("补货成功,请重新购买");context.setState(new StateA());}}
    }
  • 意图:定义算法家族,封装各算法,使它们可互换,算法变化独立于使用它们的客户端。
  • 结构
    • 策略(Strategy):声明所有支持算法的公共接口。
    • 具体策略(Concrete Strategy):实现策略接口,提供具体算法实现。
    • 上下文(Context):使用一个策略对象,维护对策略对象的引用,可允许客户端替换策略对象。
  • 适用性
    • 许多相关类仅行为不同(如不同排序算法、支付方式)。
    • 需使用算法的不同变体(如根据场景选择不同加密算法)。
    • 算法使用客户端不应知道的数据,需封装算法细节。
    • 操作含大量算法分支,用策略类替代条件语句。
  • 示例图:

10. 模板方法模式(Template Method)

  • 代码实现:
    public class StrategyPattern {public static void main(String[] args) {Strategy add = new AddStrategy();Strategy subtraction = new SubtractionStrategy();Strategy multiply = new MultiplyStrategy();OperationContext context = new OperationContext(add);context.Operation(2022, 528);context = new OperationContext(subtraction);context.Operation(2022, 528);context = new OperationContext(multiply);context.Operation(2022, 528);}
    }class OperationContext {private Strategy strategy;public OperationContext(Strategy strategy) {this.strategy = strategy;}public void Operation(int a, int b) {strategy.TwoNumberOperation(a, b);}
    }interface Strategy {public void TwoNumberOperation(int a, int b);
    }class AddStrategy implements Strategy {@Overridepublic void TwoNumberOperation(int a, int b) {System.out.println(a + b);}
    }class SubtractionStrategy implements Strategy {@Overridepublic void TwoNumberOperation(int a, int b) {System.out.println(a - b);}
    }class MultiplyStrategy implements Strategy {@Overridepublic void TwoNumberOperation(int a, int b) {System.out.println(a * b);}
    }
    
  • 意图:定义操作中算法的骨架,将某些步骤延迟到子类,使子类不改变算法结构即可重定义特定步骤。
  • 结构
    • 抽象类(Abstract Class):定义算法骨架(模板方法),包含若干抽象基本操作(由子类实现)和具体操作(子类可继承或重写)。
    • 具体子类(Concrete Class):实现抽象类的抽象基本操作,完成算法中与自身相关的步骤。
  • 适用性
    • 需一次性实现算法不变部分,将可变行为留给子类(如流程固定、步骤细节可变)。
    • 需控制子类扩展,仅允许重定义算法特定步骤(避免修改算法骨架)。
    • 多个子类有公共算法步骤,可抽为骨架减少代码重复。
  • 示例图:

11. 访问者模式(Visitor)

  • 代码实现:
    public class TemplateMethodPattern {public static void main(String[] args) {// 父类名 对象名 = new 子类名();Person student = new Student();Person teacher = new Teacher();student.TemplateMethod();System.out.println("=====我是分割线=====");teacher.TemplateMethod();}
    }abstract class Person {public void TemplateMethod() {System.out.println("上课 去教室"); // 1PrimitiveOperation1(); // 2System.out.println("下课 离开教室"); // 3PrimitiveOperation2(); // 4}public abstract void PrimitiveOperation1(); // 原语操作 1 :上课过程 学生 听课…… 老师 讲课public abstract void PrimitiveOperation2(); // 原语操作 2 :作业     学生 写作业 提交作业…… 老师 批改作业 打分数
    }class Student extends Person {@Overridepublic void PrimitiveOperation1() {System.out.println("学生:听课 学习 做笔记 提出问题");}@Overridepublic void PrimitiveOperation2() {System.out.println("学生:写作业 提交作业");}
    }class Teacher extends Person {@Overridepublic void PrimitiveOperation1() {System.out.println("老师:上课 讲课 解答问题 布置作业");}@Overridepublic void PrimitiveOperation2() {System.out.println("老师:批改作业 打分数");}
    }
  • 意图:表示作用于对象结构元素的操作,使无需改变元素类即可定义新操作。
  • 结构
    • 访问者(Visitor):声明对对象结构中每个元素的访问操作,操作名和参数标识元素类型。
    • 具体访问者(Concrete Visitor):实现访问者接口,为每个元素类实现访问操作。
    • 元素(Element):声明接收访问者的接口(accept()方法,参数为访问者)。
    • 具体元素(Concrete Element):实现accept()方法,调用访问者对应自身类型的操作。
    • 对象结构(Object Structure):包含元素集合,提供遍历元素的接口,可提供添加 / 删除元素的方法。
  • 适用性
    • 需对对象结构元素进行多组不相关操作,避免操作 “污染” 元素类(如统计、导出操作)。
    • 对象结构相对稳定,但操作易变(如很少新增元素,常新增操作)。
    • 需集中管理对象结构元素的操作(如将操作集中在访问者中便于维护)。
    • 一个对象结构包含很多类对象,它们有不同的接口。
  • 示例图:


    五、总结

    类型模式名称意图核心结构适用性
    创建型抽象工厂模式提供接口创建一系列相关 / 依赖对象,无需指定具体类抽象工厂、具体工厂、抽象产品、具体产品、客户端系统需独立于产品创建;需配置多个产品系列;强调相关产品联合使用
    构建器模式将复杂对象的构建与表示分离,使相同构建过程可生成不同表示构建器、具体构建器、指挥者、产品创建复杂对象的算法独立于部件及装配方式;需不同表示的复杂对象
    工厂方法模式定义创建对象的接口,让子类决定实例化哪类,延迟实例化到子类产品、具体产品、创建者、具体创建者类不知需创建的对象类;希望子类指定创建的对象;需动态选择实例化类
    原型模式用原型实例指定对象种类,通过复制原型创建新对象原型、具体原型、客户端类实例化消耗大;避免与产品类平行的工厂类;需动态生成对象
    单例模式保证类仅有一个实例,提供全局访问点单例(私有构造函数、静态实例、静态访问方法)类只能有一个实例且需全局访问(如配置管理器、日志管理器)
    结构型适配器模式将类的接口转换为客户期望的接口,解决接口不兼容问题目标、适配者、适配器需使用接口不符的已有类;需复用与不相关类协同工作的类
    桥接模式分离抽象与实现部分,使两者可独立变化抽象、扩展抽象、实现、具体实现不希望抽象与实现绑定;两者都需通过子类扩展;实现修改不应影响客户端
    组合模式将对象组合成树形结构表示 “部分 - 整体” 层次,统一单个与组合对象的使用组件、叶节点、组合节点需表示部分 - 整体层次(如文件系统);希望客户端统一处理单个与组合对象
    装饰器模式动态给对象添加额外职责,比子类扩展更灵活组件、具体组件、装饰器、具体装饰器需动态添加职责;需可撤销的职责;子类扩展会导致类数量爆炸
    外观模式为子系统一组接口提供统一高层接口,简化子系统使用外观、子系统类需简化复杂子系统接口;客户端与子系统多模块依赖;需构建层次化子系统
    享元模式用共享技术支持大量细粒度对象,区分内部状态(共享)与外部状态(不共享)享元、具体享元、非共享具体享元、享元工厂、客户端应用使用大量对象导致存储开销大;对象多数状态可转为外部状态
    代理模式为对象提供代理以控制访问抽象主题、真实主题、代理远程代理(跨地址空间);虚拟代理(延迟加载);保护代理(权限控制)
    行为型职责链模式使多个对象有机会处理请求,请求沿链传递直到被处理,解耦发送者与接收者处理者、具体处理者、客户端多个对象可处理请求且处理者动态确定;不明确接收者;需动态调整处理链
    命令模式将请求封装为对象,支持参数化、排队、日志、撤销命令、具体命令、客户端、调用者、接收者需抽象动作以参数化对象;需排队或记录请求;需支持撤销操作
    解释器模式定义语言文法表示,用解释器解释语言句子抽象表达式、终结符表达式、非终结符表达式、上下文、客户端语言文法简单;需解释执行的句子数量有限;需扩展文法
    迭代器模式提供顺序访问聚合对象元素的方法,不暴露内部表示迭代器、具体迭代器、聚合、具体聚合需访问聚合内容但不暴露结构;需多种遍历方式;需统一不同聚合的遍历接口
    中介者模式用中介对象封装对象交互,降低耦合,使对象独立改变交互中介者、具体中介者、同事、具体同事对象间依赖复杂(网状依赖);需定制多类分布的行为;需减少直接通信
    备忘录模式不破坏封装的前提下,捕获对象状态并外部保存,以便恢复原发器、备忘录、负责人需保存对象某时刻状态(如游戏存档);直接访问状态会破坏封装
    观察者模式定义一对多依赖,一个对象状态改变时,所有依赖对象自动更新主题、具体主题、观察者、具体观察者一个对象改变需联动其他对象;需解耦通知者与被通知者;需独立扩展双方
    状态模式允许对象内部状态改变时改变行为,使对象看似修改了自身类环境、状态、具体状态对象行为依赖状态且状态动态变化;操作含大量状态依赖的分支条件
    策略模式定义算法家族并封装,使算法可互换,独立于客户端策略、具体策略、上下文多个相关类仅行为不同;需使用算法变体;需封装算法细节
    模板方法模式定义算法骨架,将步骤延迟到子类,使子类不改变结构即可重定义步骤抽象类(模板方法 + 基本操作)、具体子类需固定算法骨架,可变步骤延迟到子类;需控制子类扩展;多子类有公共步骤
    访问者模式定义作用于对象结构元素的操作,无需修改元素类即可添加新操作访问者、具体访问者、元素、具体元素、对象结构需对对象结构元素进行多组不相关操作;对象结构稳定但操作易变;需集中管理操作
    http://www.dtcms.com/a/549213.html

    相关文章:

  • 广西建设局建设行政主管部网站企业app开发企业
  • Python 实战:Web 漏洞 Python POC 代码及原理详解(3)
  • VMware替代 | ZStack ZSphere与VMware NSX安全策略对比
  • BigDecimal
  • 【电子元器件·10】低功耗继电器 —— 磁保持继电器;有源蜂鸣器、无源蜂鸣器
  • 示范专业网站建设网站开发体会范文
  • LeetCode 411 - 最短独占单词缩写
  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段-二阶段(11):文法和单词-第三课
  • 网站建设方案和报价家装设计师工资高吗
  • 虚拟环境配置
  • 高效学习《数据库原理》:从理论到实战的计算机专业指南
  • 龙口网站设计网站文件夹没有权限设置
  • Vue3+CSS 实现3D卡片动画
  • RabbitMQ面试全解析:从核心概念到高可用架构
  • MATLAB数据读取全攻略从TXT到音视频的详细方法解析
  • 用ps做网站切片高级感ppt模板免费
  • 21.动态NAT
  • Java的进化之路:从面向对象到云原生时代的全面突破
  • 本期总结与导读
  • 机器学习日报08
  • 【PostgreSQL】Docker下的postgresSQL的查询
  • 衡阳网站seo优化建立网站需要多少钱一个
  • 广州市白云区建设局 网站南同网站建设
  • 东软专业力考试--Java面向对象编程
  • ZCC5050是一款高性能的高侧 OR-ing FET 控制器替代LM5050
  • 织梦网站怎么做索引地图公司注册信息查询系统
  • 扩展阅读:JSON 简介
  • AR眼镜 + 海关:智慧通关技术方案解析|阿法龙XR云平台
  • 海南省建设信息官方网站做网站专业公司
  • DoIP协议常用数据类型及其使用场景详解