LarryDpk
发布于 2025-04-14 / 12 阅读
0

Gang of Four(GoF)设计模式

Gang of Four(GoF)设计模式

GoF概述

以下是Gang of Four(GoF)的23种设计模式,分为创建型结构型行为型三类,结合其背景、设计原则及核心思想进行解释:


一、创建型模式(5种)

目标:解耦对象的创建过程,提供灵活的对象创建机制。

1. 单例模式(Singleton)

  • 背景:确保一个类仅有一个实例,并提供全局访问点(如数据库连接池)。
  • 原则:单一职责原则(一个类只管理自身实例)。
  • 核心:私有构造函数 + 静态方法控制实例化。

2. 工厂方法(Factory Method)

  • 背景:将对象创建延迟到子类,避免代码与具体类耦合(如UI库中的跨平台组件创建)。
  • 原则:依赖倒置原则(依赖抽象而非具体类)。
  • 核心:定义一个创建对象的接口,子类决定实例化哪个类。

3. 抽象工厂(Abstract Factory)

  • 背景:创建一组相关或依赖对象的家族(如不同操作系统的UI控件套件)。
  • 原则:开闭原则(扩展新家族无需修改已有代码)。
  • 核心:抽象接口声明多个创建方法,每个具体工厂实现一个产品族。

4. 建造者(Builder)

  • 背景:分步骤构造复杂对象(如构造包含多个部件的HTML文档)。
  • 原则:单一职责原则(构造过程与表示分离)。
  • 核心:导演类指导构造步骤,建造者实现具体构造细节。

5. 原型模式(Prototype)

  • 背景:通过复制现有对象来创建新对象(如游戏中的敌人克隆)。
  • 原则:减少重复初始化成本。
  • 核心:实现Cloneable接口,深拷贝或浅拷贝对象。

二、结构型模式(7种)

目标:组合类或对象形成更大的结构。

6. 适配器(Adapter)

  • 背景:使不兼容接口协同工作(如将旧版API适配到新系统)。
  • 原则:接口隔离原则(客户端仅依赖所需接口)。
  • 核心:包装旧类,实现新接口(类适配器继承,对象适配器组合)。

7. 桥接(Bridge)

  • 背景:分离抽象与实现,使两者独立变化(如不同形状与颜色的组合)。
  • 原则:组合优于继承。
  • 核心:抽象类持有实现接口的引用,解耦功能层次。

8. 组合(Composite)

  • 背景:以树形结构处理部分-整体关系(如文件系统)。
  • 原则:透明性(叶节点与组合节点接口一致)。
  • 核心:组件接口定义默认行为,叶节点和容器统一处理。

9. 装饰器(Decorator)

  • 背景:动态添加职责(如为流添加压缩/加密功能)。
  • 原则:开闭原则(扩展功能不修改原有类)。
  • 核心:包装对象并实现相同接口,递归叠加功能。

10. 外观(Facade)

  • 背景:简化复杂子系统的调用(如一键启动电脑)。
  • 原则:最少知识原则(客户端仅与外观交互)。
  • 核心:提供统一高层接口,隐藏子系统细节。

11. 享元(Flyweight)

  • 背景:共享细粒度对象以减少内存占用(如文档中的字符对象池)。
  • 原则:分离内部状态(共享)与外部状态(上下文相关)。
  • 核心:工厂管理共享对象,客户端传递外部状态。

12. 代理(Proxy)

  • 背景:控制对象访问(如远程代理、懒加载图片)。
  • 原则:职责分离(代理类处理附加逻辑)。
  • 核心:代理类与真实类实现同一接口,代理控制访问。

三、行为型模式(11种)

目标:管理对象间的交互与职责分配。

13. 策略(Strategy)

  • 背景:动态切换算法(如排序算法切换)。
  • 原则:开闭原则(新增策略无需修改上下文)。
  • 核心:定义策略接口,上下文类持有策略引用。

14. 模板方法(Template Method)

  • 背景:定义算法骨架,子类重写步骤(如冲泡饮料流程)。
  • 原则:好莱坞原则(“不要调用我们,我们会调用你”)。
  • 核心:抽象类定义模板方法,具体子类实现可变步骤。

15. 观察者(Observer)

  • 背景:一对多依赖通知(如事件监听系统)。
  • 原则:松耦合(主题与观察者独立变化)。
  • 核心:主题维护观察者列表,状态变化时通知所有观察者。

16. 迭代器(Iterator)

  • 背景:统一遍历集合元素的方式(如不同数据结构的遍历)。
  • 原则:单一职责原则(遍历与集合分离)。
  • 核心:定义hasNext()next()接口,集合类提供迭代器。

17. 责任链(Chain of Responsibility)

  • 背景:解耦请求发送者与处理者(如审批流程)。
  • 原则:动态组合处理链。
  • 核心:每个处理器决定是否处理请求或传递给下一节点。

18. 命令(Command)

  • 背景:将请求封装为对象(如支持撤销的操作队列)。
  • 原则:参数化客户端与操作。
  • 核心:命令接口定义执行方法,调用者调用命令对象。

19. 备忘录(Memento)

  • 背景:捕获对象状态以便恢复(如文档撤销功能)。
  • 原则:封装状态保存细节。
  • 核心:原发者生成备忘录,管理者存储备忘录。

20. 状态(State)

  • 背景:对象行为随状态改变(如订单状态流转)。
  • 原则:将状态转移逻辑封装到状态类中。
  • 核心:上下文类持有状态对象,委托行为给当前状态。

21. 访问者(Visitor)

  • 背景:在不修改类的前提下添加新操作(如统计不同类型元素)。
  • 原则:双重分派(通过accept方法传递访问者)。
  • 核心:访问者接口定义针对不同元素的visit方法。

22. 中介者(Mediator)

  • 背景:减少对象间直接通信(如聊天室协调消息)。
  • 原则:迪米特法则(对象仅与中介者交互)。
  • 核心:中介者封装对象交互逻辑。

23. 解释器(Interpreter)

  • 背景:定义语言的文法表示(如SQL解析、正则表达式)。
  • 原则:将语法规则表示为类。
  • 核心:抽象语法树(AST)由多个表达式类组合而成。

四、设计模式的核心原则

  1. 封装变化:将易变部分独立(如策略模式封装算法)。
  2. 面向接口:依赖抽象而非具体实现。
  3. 组合优于继承:通过组合实现灵活的功能扩展。
  4. 松耦合:减少对象间的直接依赖。

GoF模式通过上述原则,帮助构建可复用、可扩展且易于维护的软件系统。

创建型设计模式-Java示例

以下是 创建型设计模式Java 示例代码 及详细解释,每种模式均附典型应用场景和实现核心思想:


1. 单例模式(Singleton)

场景:全局唯一配置管理类。 核心:确保一个类只有一个实例,并提供全局访问点。

public class ConfigManager {  
 private static volatile ConfigManager instance; // volatile 防止指令重排序  
 private String configData;  
 // 私有构造函数  
 private ConfigManager() { configData = "默认配置";  
 }  
 // 双重检查锁定(Double-Checked Locking)  
 public static ConfigManager getInstance() { if (instance == null) { synchronized (ConfigManager.class) { if (instance == null) { instance = new ConfigManager(); } } } return instance; }  
 public String getConfig() { return configData; }  
 public void updateConfig(String data) { configData = data; }}  
  
// 使用示例  
ConfigManager config = ConfigManager.getInstance();  
System.out.println(config.getConfig()); // 输出: 默认配置  

关键点

  • 私有构造函数防止外部实例化。
  • volatile + 双重检查锁定确保线程安全。
  • 适用于需要全局唯一访问点的资源(如数据库连接池、日志管理器)。

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

场景:跨平台按钮创建。 核心:定义创建对象的接口,由子类决定实例化哪个类。

// 抽象产品接口  
interface Button {  
 void render();}  
  
// 具体产品:Windows 按钮  
class WindowsButton implements Button {  
 @Override public void render() { System.out.println("渲染一个Windows风格的按钮");  
 }}  
  
// 抽象创建者类(工厂)  
abstract class Dialog {  
 public abstract Button createButton(); // 工厂方法  
  
 public void renderDialog() { Button button = createButton(); button.render(); }}  
  
// 具体创建者:Windows 对话框  
class WindowsDialog extends Dialog {  
 @Override public Button createButton() { return new WindowsButton(); }}  
  
// 使用示例  
Dialog dialog = new WindowsDialog();  
dialog.renderDialog(); // 输出: 渲染一个Windows风格的按钮  

关键点

  • 将对象创建延迟到子类,解耦客户端代码与具体类。
  • 符合 开闭原则(新增产品类型只需扩展子类)。

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

场景:创建跨平台UI组件套件(按钮+复选框)。 核心:提供一个接口,用于创建相关或依赖对象的家族。

// 抽象产品接口  
interface Button { void render(); }  
interface Checkbox { void check(); }  
  
// 具体产品族:Windows风格组件  
class WindowsButton implements Button {  
 @Override public void render() { System.out.println("Windows按钮"); }  
}  
  
class WindowsCheckbox implements Checkbox {  
 @Override public void check() { System.out.println("Windows复选框被选中"); }  
}  
  
// 抽象工厂接口  
interface GUIFactory {  
 Button createButton(); Checkbox createCheckbox();}  
  
// 具体工厂:Windows组件工厂  
class WindowsFactory implements GUIFactory {  
 @Override public Button createButton() { return new WindowsButton(); } @Override public Checkbox createCheckbox() { return new WindowsCheckbox(); }}  
  
// 客户端代码  
public class Application {  
 private Button button; private Checkbox checkbox;  
 public Application(GUIFactory factory) { button = factory.createButton(); checkbox = factory.createCheckbox(); }  
 public void paint() { button.render(); checkbox.check(); }}  
  
// 使用示例  
Application app = new Application(new WindowsFactory());  
app.paint();  
// 输出:  
// Windows按钮  
// Windows复选框被选中  

关键点

  • 一个工厂类创建同一产品族的所有对象(如Windows/Mac风格组件)。
  • 新增产品族(如MacFactory)时,无需修改客户端代码。

4. 建造者模式(Builder)

场景:构造复杂对象(如电脑配置)。 核心:分步骤构建复杂对象,分离构造过程与表示。

// 最终产品  
class Computer {  
 private String CPU; private String RAM; private String storage;  
 public void setCPU(String cpu) { this.CPU = cpu; } public void setRAM(String ram) { this.RAM = ram; } public void setStorage(String storage) { this.storage = storage; }  
 @Override public String toString() { return "Computer [CPU=" + CPU + ", RAM=" + RAM + ", Storage=" + storage + "]"; }}  
  
// 抽象建造者  
interface ComputerBuilder {  
 void buildCPU(); void buildRAM(); void buildStorage(); Computer getResult();}  
  
// 具体建造者:游戏电脑配置  
class GamingComputerBuilder implements ComputerBuilder {  
 private Computer computer = new Computer();  
 @Override public void buildCPU() { computer.setCPU("Intel i9"); }  
 @Override public void buildRAM() { computer.setRAM("32GB DDR5"); }  
 @Override public void buildStorage() { computer.setStorage("1TB NVMe SSD"); }  
 @Override public Computer getResult() { return computer; }}  
  
// 导演类(控制建造流程)  
class Director {  
 public Computer construct(ComputerBuilder builder) { builder.buildCPU(); builder.buildRAM(); builder.buildStorage(); return builder.getResult(); }}  
  
// 使用示例  
Director director = new Director();  
ComputerBuilder builder = new GamingComputerBuilder();  
Computer computer = director.construct(builder);  
System.out.println(computer); // 输出: Computer [CPU=Intel i9, RAM=32GB DDR5, Storage=1TB NVMe SSD]  

关键点

  • 分离对象的构造代码(Builder)与业务逻辑代码(Director)。
  • 支持分步骤构造对象,灵活应对不同配置需求。

5. 原型模式(Prototype)

场景:克隆游戏中的敌人对象。 核心:通过复制现有对象创建新对象,避免重复初始化开销。

// 实现 Cloneable 接口  
class Enemy implements Cloneable {  
 private String type; private int health;  
 public Enemy(String type, int health) { this.type = type; this.health = health; System.out.println("复杂初始化过程..."); // 模拟耗时操作  
 }  
 @Override protected Enemy clone() throws CloneNotSupportedException { return (Enemy) super.clone(); // 浅拷贝  
 }  
 public String getType() { return type; } public int getHealth() { return health; }}  
  
// 使用示例  
Enemy original = new Enemy("僵尸", 100); // 输出: 复杂初始化过程...  
try {  
 Enemy clone = original.clone(); // 不会触发复杂初始化  
 System.out.println(clone.getType() + "克隆体,血量:" + clone.getHealth()); // 输出: 僵尸克隆体,血量:100  
} catch (CloneNotSupportedException e) {  
 e.printStackTrace();}  

关键点

  • 通过 clone() 方法快速复制对象,避免重复执行初始化代码。
  • 深拷贝与浅拷贝需根据场景处理(示例为浅拷贝)。

总结

模式 核心思想 适用场景
单例模式 全局唯一实例 配置管理、日志系统
工厂方法 子类决定创建对象 跨平台组件、插件扩展
抽象工厂 创建产品家族 UI风格套件、跨数据库访问
建造者模式 分步骤构造复杂对象 配置复杂的对象(如订单)
原型模式 克隆对象减少初始化开销 游戏实体克隆、缓存模板

设计原则

  • 单一职责:每个类/方法只做一件事(如建造者分离构造逻辑)。
  • 开闭原则(工厂方法、抽象工厂):通过扩展而非修改应对变化。
  • 依赖倒置(工厂模式):客户端依赖抽象接口而非具体实现。

结构型设计模式-Java示例

以下是 结构型设计模式Java 示例代码 及详细解释,每种模式均附典型应用场景和实现核心思想:


1. 适配器模式(Adapter)

场景:将旧版日志系统适配到新接口 核心:将一个类的接口转换成客户端期望的另一个接口。

// 旧版日志类(需适配的类)  
class LegacyLogger {  
 public void logMessage(String message) { System.out.println("[Legacy] " + message); }}  
  
// 新日志接口(目标接口)  
interface NewLogger {  
 void log(String message);}  
  
// 适配器类(对象适配器)  
class LoggerAdapter implements NewLogger {  
 private LegacyLogger legacyLogger;  
 public LoggerAdapter(LegacyLogger legacyLogger) { this.legacyLogger = legacyLogger; }  
 @Override public void log(String message) { // 转换逻辑:添加时间戳  
 String formattedMsg = "[Time] " + System.currentTimeMillis() + " - " + message; legacyLogger.logMessage(formattedMsg); }}  
  
// 使用示例  
NewLogger logger = new LoggerAdapter(new LegacyLogger());  
logger.log("用户登录成功"); // 输出: [Legacy] [Time] 1620000000000 - 用户登录成功  

关键点

  • 通过组合旧类对象实现接口转换(对象适配器)
  • 解决新旧系统接口不兼容问题
  • 符合 开闭原则(无需修改原有代码)

2. 桥接模式(Bridge)

场景:分离图形形状与颜色实现 核心:将抽象与实现解耦,使两者可以独立变化。

// 实现部分接口(颜色)  
interface Color {  
 String fill();}  
  
class Red implements Color {  
 public String fill() { return "红色"; }  
}  
  
class Blue implements Color {  
 public String fill() { return "蓝色"; }  
}  
  
// 抽象部分(形状)  
abstract class Shape {  
 protected Color color;  
 public Shape(Color color) { this.color = color; }  
 abstract String draw();}  
  
class Circle extends Shape {  
 public Circle(Color color) { super(color); }  
 public String draw() { return color.fill() + "圆形";  
 }}  
  
class Square extends Shape {  
 public Square(Color color) { super(color); }  
 public String draw() { return color.fill() + "方形";  
 }}  
  
// 使用示例  
Shape redCircle = new Circle(new Red());  
System.out.println(redCircle.draw()); // 输出: 红色圆形  
  
Shape blueSquare = new Square(new Blue());  
System.out.println(blueSquare.draw()); // 输出: 蓝色方形  

关键点

  • 使用组合代替继承(形状持有颜色对象)
  • 新增颜色/形状类型互不影响
  • 符合 单一职责原则

3. 组合模式(Composite)

场景:文件系统目录结构 核心:以树形结构处理部分-整体关系,统一叶子与容器接口。

// 组件接口  
interface FileSystemComponent {  
 void display(int indent);}  
  
// 叶子节点(文件)  
class File implements FileSystemComponent {  
 private String name;  
 public File(String name) { this.name = name; }  
 public void display(int indent) { System.out.println(" ".repeat(indent) + "📄 " + name); }}  
  
// 复合节点(目录)  
class Directory implements FileSystemComponent {  
 private String name; private List<FileSystemComponent> children = new ArrayList<>();  
 public Directory(String name) { this.name = name; }  
 public void add(FileSystemComponent component) { children.add(component); }  
 public void display(int indent) { System.out.println(" ".repeat(indent) + "📁 " + name); for (FileSystemComponent child : children) { child.display(indent + 2); } }}  
  
// 使用示例  
Directory root = new Directory("根目录");  
root.add(new File("简历.pdf"));  
  
Directory codeDir = new Directory("代码");  
codeDir.add(new File("Main.java"));  
codeDir.add(new File("Utils.java"));  
root.add(codeDir);  
  
root.display(0);  
/* 输出:  
📁 根目录  
 📄 简历.pdf  
  📁 代码  
 📄 Main.java  📄 Utils.java*/  

关键点

  • 统一处理叶子对象与容器对象
  • 支持递归结构操作
  • 符合 透明性原则(叶子与容器接口一致)

4. 装饰器模式(Decorator)

场景:咖啡加料系统 核心:动态扩展对象功能,避免子类爆炸。

// 组件接口  
interface Coffee {  
 String getDescription(); double cost();}  
  
// 具体组件(基础咖啡)  
class SimpleCoffee implements Coffee {  
 public String getDescription() { return "普通咖啡"; }  
 public double cost() { return 10.0; }}  
  
// 抽象装饰器  
abstract class CoffeeDecorator implements Coffee {  
 protected Coffee decoratedCoffee;  
 public CoffeeDecorator(Coffee coffee) { this.decoratedCoffee = coffee; }  
 public String getDescription() { return decoratedCoffee.getDescription(); }  
 public double cost() { return decoratedCoffee.cost(); }}  
  
// 具体装饰器:加牛奶  
class MilkDecorator extends CoffeeDecorator {  
 public MilkDecorator(Coffee coffee) { super(coffee); }  
 public String getDescription() { return super.getDescription() + " + 牛奶";  
 }  
 public double cost() { return super.cost() + 3.0; }}  
  
// 具体装饰器:加糖  
class SugarDecorator extends CoffeeDecorator {  
 public SugarDecorator(Coffee coffee) { super(coffee); }  
 public String getDescription() { return super.getDescription() + " + 糖";  
 }  
 public double cost() { return super.cost() + 1.0; }}  
  
// 使用示例  
Coffee coffee = new SimpleCoffee();  
coffee = new MilkDecorator(coffee);  
coffee = new SugarDecorator(coffee);  
  
System.out.println(coffee.getDescription() + ",价格:" + coffee.cost());  
// 输出: 普通咖啡 + 牛奶 + 糖,价格:14.0  

关键点

  • 通过包装对象实现功能叠加
  • 符合 开闭原则(新增装饰器无需修改现有代码)
  • 避免继承导致的类爆炸问题

5. 外观模式(Facade)

场景:一键启动电脑 核心:为复杂子系统提供统一入口。

// 子系统1:CPU  
class CPU {  
 void start() { System.out.println("CPU启动"); }  
}  
  
// 子系统2:内存  
class Memory {  
 void load() { System.out.println("内存加载"); }  
}  
  
// 子系统3:硬盘  
class HardDrive {  
 void read() { System.out.println("硬盘读取"); }  
}  
  
// 外观类  
class ComputerFacade {  
 private CPU cpu = new CPU(); private Memory memory = new Memory(); private HardDrive hardDrive = new HardDrive();  
 public void startComputer() { cpu.start(); memory.load(); hardDrive.read(); System.out.println("电脑启动完成");  
 }}  
  
// 使用示例  
ComputerFacade computer = new ComputerFacade();  
computer.startComputer();  
/* 输出:  
CPU启动  
内存加载  
硬盘读取  
电脑启动完成  
*/  

关键点

  • 简化客户端与子系统的交互
  • 符合 最少知识原则(客户端只需与外观类交互)
  • 降低系统耦合度

6. 享元模式(Flyweight)

场景:游戏粒子系统 核心:共享大量细粒度对象,减少内存消耗。

// 享元对象(内部状态)  
class ParticleType {  
 private final String texture; private final String color;  
 public ParticleType(String texture, String color) { this.texture = texture; this.color = color; }  
 public void draw(int x, int y) {  // 外部状态由参数传入  
 System.out.printf("在(%d,%d)绘制[%s][%s]粒子\n", x, y, texture, color);  
 }}  
  
// 享元工厂  
class ParticleFactory {  
 private static Map<String, ParticleType> cache = new HashMap<>();  
 public static ParticleType getParticleType(String texture, String color) { String key = texture + "_" + color; if (!cache.containsKey(key)) { cache.put(key, new ParticleType(texture, color)); } return cache.get(key); }}  
  
// 客户端使用  
ParticleType fire = ParticleFactory.getParticleType("火焰", "红色");  
fire.draw(10, 20);  // 在(10,20)绘制[火焰][红色]粒子  
  
ParticleType water = ParticleFactory.getParticleType("水花", "蓝色");  
water.draw(30, 40); // 在(30,40)绘制[水花][蓝色]粒子  
  
// 复用已有享元对象  
ParticleType fire2 = ParticleFactory.getParticleType("火焰", "红色");  
System.out.println(fire == fire2); // 输出: true  

关键点

  • 分离内部状态(共享)与外部状态(每次传入)
  • 使用工厂管理共享对象池
  • 适用于需要创建大量相似对象的场景

7. 代理模式(Proxy)

场景:图片懒加载 核心:控制对象访问,实现延迟加载或访问控制。

// 接口  
interface Image {  
 void display();}  
  
// 真实对象  
class RealImage implements Image {  
 private String filename;  
 public RealImage(String filename) { this.filename = filename; loadFromDisk(); // 初始化时立即加载  
 }  
 private void loadFromDisk() { System.out.println("加载图片: " + filename);  
 }  
 public void display() { System.out.println("显示图片: " + filename);  
 }}  
  
// 代理类  
class ProxyImage implements Image {  
 private String filename; private RealImage realImage;  
 public ProxyImage(String filename) { this.filename = filename; }  
 public void display() { if (realImage == null) {  // 延迟加载  
 realImage = new RealImage(filename); } realImage.display(); }}  
  
// 使用示例  
Image image = new ProxyImage("photo.jpg");  
// 此时尚未加载真实图片  
image.display();  // 首次调用时加载并显示  
/* 输出:  
加载图片: photo.jpg  
显示图片: photo.jpg  
*/  

关键点

  • 代理与真实对象实现相同接口
  • 实现延迟加载、访问控制等附加功能
  • 符合 单一职责原则(代理处理附加逻辑)

结构型模式总结

模式 核心思想 典型应用场景
适配器 接口转换 新旧系统兼容
桥接 抽象与实现分离 多维度变化的系统
组合 树形结构统一处理 文件系统、UI组件
装饰器 动态添加功能 IO流增强、GUI组件扩展
外观 简化复杂子系统访问 框架封装、API网关
享元 共享细粒度对象 游戏粒子、文档字符
代理 控制对象访问 懒加载、权限控制、远程代理

共同原则

  1. 组合优于继承(桥接、装饰器)
  2. 接口隔离(适配器、代理)
  3. 关注点分离(外观、享元)

通过合理使用结构型模式,可以构建更灵活、可维护的软件架构,有效管理对象之间的复杂关系。

行为型设计模式-Java示例

以下是 行为型设计模式Java 示例代码 及详细解释,涵盖所有11种模式,附典型场景和核心思想:


1. 策略模式(Strategy)

场景:动态切换支付方式 核心:将算法封装为独立对象,支持运行时切换。

interface PaymentStrategy {  
 void pay(int amount);}  
  
class CreditCardPayment implements PaymentStrategy {  
 public void pay(int amount) { System.out.println("信用卡支付:" + amount + "元");  
 }}  
  
class AlipayPayment implements PaymentStrategy {  
 public void pay(int amount) { System.out.println("支付宝支付:" + amount + "元");  
 }}  
  
class ShoppingCart {  
 private PaymentStrategy strategy;  
 public void setStrategy(PaymentStrategy strategy) { this.strategy = strategy; }  
 public void checkout(int amount) { strategy.pay(amount); }}  
  
// 使用示例  
ShoppingCart cart = new ShoppingCart();  
cart.setStrategy(new AlipayPayment());  
cart.checkout(100); // 输出: 支付宝支付:100元  

关键点

  • 算法族独立变化,符合 开闭原则
  • 避免多重条件判断语句

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

场景:定义饮料制作流程 核心:父类定义算法骨架,子类实现具体步骤。

abstract class Beverage {  
 // 模板方法(final防止子类覆盖)  
 final void prepareRecipe() { boilWater(); brew(); pourInCup(); addCondiments(); }  
 abstract void brew(); abstract void addCondiments();  
 void boilWater() { System.out.println("烧水");  
 }  
 void pourInCup() { System.out.println("倒入杯子");  
 }}  
  
class Coffee extends Beverage {  
 void brew() { System.out.println("冲泡咖啡粉"); }  
 void addCondiments() { System.out.println("加糖和牛奶"); }  
}  
  
// 使用示例  
Beverage coffee = new Coffee();  
coffee.prepareRecipe();  
/* 输出:  
烧水  
冲泡咖啡粉  
倒入杯子  
加糖和牛奶  
*/  

关键点

  • 父类控制流程,子类扩展细节
  • 符合 好莱坞原则(“不要调用我们,我们会调用你”)

3. 观察者模式(Observer)

场景:新闻发布订阅系统 核心:定义对象间的一对多依赖,状态变化自动通知。

import java.util.ArrayList;  
import java.util.List;  
  
class NewsPublisher {  
 private List<Observer> observers = new ArrayList<>(); private String news;  
 public void addObserver(Observer o) { observers.add(o); }  
 public void setNews(String news) { this.news = news; notifyObservers(); }  
 private void notifyObservers() { for (Observer o : observers) { o.update(news); } }}  
  
interface Observer {  
 void update(String news);}  
  
class User implements Observer {  
 public void update(String news) { System.out.println("收到新闻: " + news);  
 }}  
  
// 使用示例  
NewsPublisher publisher = new NewsPublisher();  
publisher.addObserver(new User());  
publisher.setNews("重大突破!"); // 输出: 收到新闻: 重大突破!  

关键点

  • 松耦合设计,主题与观察者独立变化
  • Java内置 java.util.Observable 可实现类似功能

4. 迭代器模式(Iterator)

场景:统一遍历不同类型集合 核心:提供遍历集合元素的统一接口。

interface Iterator<T> {  
 boolean hasNext(); T next();}  
  
class BookList {  
 private String[] books = {"Java", "Python", "C++"};     public Iterator<String> iterator() {  
 return new BookIterator(); }  
 private class BookIterator implements Iterator<String> { private int index = 0;  
 public boolean hasNext() { return index < books.length; }  
 public String next() { return books[index++]; } }}  
  
// 使用示例  
BookList list = new BookList();  
Iterator<String> it = list.iterator();  
while (it.hasNext()) {  
 System.out.println(it.next()); // 依次输出: Java Python C++  
}  

关键点

  • 分离集合结构与遍历逻辑
  • Java集合框架已广泛使用此模式

5. 责任链模式(Chain of Responsibility)

场景:多级审批流程 核心:将请求沿处理链传递,直到被处理。

abstract class Approver {  
 protected Approver next;  
 public void setNext(Approver next) { this.next = next; }  
 public abstract void processRequest(int amount);}  
  
class Manager extends Approver {  
 public void processRequest(int amount) { if (amount <= 1000) { System.out.println("经理审批通过");  
 } else if (next != null) { next.processRequest(amount); } }}  
  
class Director extends Approver {  
 public void processRequest(int amount) { if (amount <= 5000) { System.out.println("总监审批通过");  
 } else if (next != null) { next.processRequest(amount); } }}  
  
// 使用示例  
Approver manager = new Manager();  
Approver director = new Director();  
manager.setNext(director);  
  
manager.processRequest(3000); // 输出: 总监审批通过  

关键点

  • 动态构建处理链
  • 请求发送者无需知道具体处理者

6. 命令模式(Command)

场景:支持撤销的操作队列 核心:将请求封装为对象,支持日志、队列和撤销。

interface Command {  
 void execute(); void undo();}  
  
class Light {  
 void on() { System.out.println("开灯"); }  
 void off() { System.out.println("关灯"); }  
}  
  
class LightOnCommand implements Command {  
 private Light light;  
 public LightOnCommand(Light light) { this.light = light; }  
 public void execute() { light.on(); } public void undo() { light.off(); }}  
  
class RemoteControl {  
 private Command command;  
 public void setCommand(Command command) { this.command = command; }  
 public void pressButton() { command.execute(); }  
 public void pressUndo() { command.undo(); }}  
  
// 使用示例  
Light light = new Light();  
Command lightOn = new LightOnCommand(light);  
RemoteControl remote = new RemoteControl();  
  
remote.setCommand(lightOn);  
remote.pressButton(); // 输出: 开灯  
remote.pressUndo();   // 输出: 关灯  

关键点

  • 将请求参数化
  • 支持事务、队列和撤销操作

7. 备忘录模式(Memento)

场景:文本编辑器撤销功能 核心:捕获对象状态并在需要时恢复。

class Editor {  
 private String content;  
 public void write(String content) { this.content = content; }  
 public Memento save() { return new Memento(content); }  
 public void restore(Memento m) { content = m.getContent(); }  
 public String getContent() { return content; }}  
  
class Memento {  
 private final String content;  
 public Memento(String content) { this.content = content; }  
 public String getContent() { return content; }}  
  
class History {  
 private Stack<Memento> states = new Stack<>();  
 public void push(Memento m) { states.push(m); } public Memento pop() { return states.pop(); }}  
  
// 使用示例  
Editor editor = new Editor();  
History history = new History();  
  
editor.write("第一版");  
history.push(editor.save()); // 保存状态  
  
editor.write("第二版");  
editor.restore(history.pop()); // 恢复到第一版  
System.out.println(editor.getContent()); // 输出: 第一版  

关键点

  • 严格封装状态保存细节
  • 适用于需要快照功能的场景

8. 状态模式(State)

场景:订单状态流转 核心:对象行为随内部状态改变而改变。

interface OrderState {  
 void handle(Order order);}  
  
class NewOrder implements OrderState {  
 public void handle(Order order) { System.out.println("处理新订单");  
 order.setState(new Shipped()); }}  
  
class Shipped implements OrderState {  
 public void handle(Order order) { System.out.println("订单已发货");  
 order.setState(new Delivered()); }}  
  
class Order {  
 private OrderState state;  
 public Order() { state = new NewOrder(); }  
 public void setState(OrderState state) { this.state = state; }  
 public void process() { state.handle(this); }}  
  
// 使用示例  
Order order = new Order();  
order.process(); // 输出: 处理新订单 → 状态变为Shipped  
order.process(); // 输出: 订单已发货 → 状态变为Delivered  

关键点

  • 将状态转移逻辑封装到状态类中
  • 消除庞大的条件判断语句

9. 访问者模式(Visitor)

场景:文档元素统计 核心:在不修改类结构的前提下添加新操作。

interface Element {  
 void accept(Visitor visitor);}  
  
class TextElement implements Element {  
 public void accept(Visitor visitor) { visitor.visit(this); }}  
  
class ImageElement implements Element {  
 public void accept(Visitor visitor) { visitor.visit(this); }}  
  
interface Visitor {  
 void visit(TextElement text); void visit(ImageElement image);}  
  
class CountVisitor implements Visitor {  
 private int textCount = 0; private int imageCount = 0;  
 public void visit(TextElement text) { textCount++; } public void visit(ImageElement image) { imageCount++; }  
 public void report() { System.out.println("文本元素: " + textCount + " 图片元素: " + imageCount);  
 }}  
  
// 使用示例  
List<Element> elements = Arrays.asList(new TextElement(), new ImageElement());  
CountVisitor visitor = new CountVisitor();  
  
for (Element e : elements) {  
 e.accept(visitor);}  
  
visitor.report(); // 输出: 文本元素: 1 图片元素: 1  

关键点

  • 通过双重分派实现操作扩展
  • 适合数据结构稳定但操作频繁变化的场景

10. 中介者模式(Mediator)

场景:聊天室协调消息 核心:通过中介者对象封装对象间的交互。

class ChatUser {  
 private String name; private ChatMediator mediator;  
 public ChatUser(String name, ChatMediator mediator) { this.name = name; this.mediator = mediator; }  
 public void send(String message) { mediator.sendMessage(message, this); }  
 public void receive(String message) { System.out.println(name + " 收到消息: " + message);  
 }}  
  
interface ChatMediator {  
 void sendMessage(String msg, ChatUser user);}  
  
class ChatRoom implements ChatMediator {  
 private List<ChatUser> users = new ArrayList<>();  
 public void addUser(ChatUser user) { users.add(user); }  
 public void sendMessage(String msg, ChatUser sender) { for (ChatUser u : users) { if (u != sender) u.receive(msg); } }}  
  
// 使用示例  
ChatRoom room = new ChatRoom();  
ChatUser alice = new ChatUser("Alice", room);  
ChatUser bob = new ChatUser("Bob", room);  
room.addUser(alice);  
room.addUser(bob);  
  
alice.send("你好!"); // Bob收到消息: 你好!  

关键点

  • 减少对象间的直接耦合
  • 集中控制交互逻辑

11. 解释器模式(Interpreter)

场景:简单布尔表达式解析 核心:定义语言的文法,并用解释器解释语句。

interface Expression {  
 boolean interpret(String context);}  
  
class TerminalExpression implements Expression {  
 private String data;  
 public TerminalExpression(String data) { this.data = data; }  
 public boolean interpret(String context) { return context.contains(data); }}  
  
class OrExpression implements Expression {  
 private Expression expr1; private Expression expr2;  
 public OrExpression(Expression e1, Expression e2) { this.expr1 = e1; this.expr2 = e2; }  
 public boolean interpret(String context) { return expr1.interpret(context) || expr2.interpret(context); }}  
  
// 使用示例  
Expression john = new TerminalExpression("John");  
Expression married = new TerminalExpression("Married");  
Expression expression = new OrExpression(john, married);  
  
System.out.println(expression.interpret("John")); // true  
System.out.println(expression.interpret("Married")); // true  
System.out.println(expression.interpret("Single")); // false  

关键点

  • 构建抽象语法树(AST)解释语言
  • 适用于特定领域语言(DSL)

行为型模式总结

模式 核心思想 典型应用场景
策略模式 算法封装,动态切换 支付方式、排序算法
模板方法 父类定义流程,子类实现步骤 框架流程控制
观察者模式 发布-订阅机制 事件处理、消息通知
迭代器模式 统一遍历接口 集合遍历
责任链模式 请求沿链传递 审批流程、过滤器链
命令模式 请求封装为对象 撤销操作、任务队列
备忘录模式 对象状态快照 撤销/恢复功能
状态模式 对象行为随状态改变 订单状态、游戏角色状态
访问者模式 分离数据结构与操作 文档处理、编译器
中介者模式 集中管理对象交互 聊天系统、GUI组件协调
解释器模式 定义语法规则 SQL解析、正则表达式

设计原则体现

  1. 开闭原则:策略模式、访问者模式支持扩展
  2. 单一职责:命令模式分离调用与执行
  3. 松耦合:观察者模式解耦主题与观察者

通过合理应用行为型模式,可以高效管理对象间的交互逻辑,提升代码的可维护性和扩展性。