设计模式
第一部分 设计模式与设计原则
设计模式概述
创建型模式(Creational Patterns)
- 工厂模式(Factory):通过工厂类统一创建对象,隐藏实例化细节
- 单例模式(Singleton):确保一个类只有一个实例,并提供全局访问点
- 建造者模式(Builder):分步骤构建复杂对象,分离构造过程与表示
- 原型模式(Prototype):通过克隆已有对象创建新对象,避免重复初始化
结构型模式(Structural Patterns)
- 适配器模式(Adapter):兼容不兼容接口,使类协同工作
- 装饰器模式(Decorator):动态地为对象添加职责,避免继承爆炸
- 代理模式(Proxy):为对象提供代理,控制对原对象的访问(如延迟加载、权限控制)
- 组合模式(Composite):以树形结构处理整体-部分关系,统一对待单个对象和组合对象
行为型模式(Behavioral Patterns)
- 观察者模式(Observer):定义对象间的一对多依赖,当一个对象状态改变时,自动通知依赖对象
- 策略模式(Strategy):定义算法族,封装每个算法,使其可互相替换
- 责任链模式(Chain of Responsibility):将请求的发送者与接收者解耦,允许多个对象处理请求
- 模板方法模式(Template Method):定义算法骨架,将某些步骤延迟到子类实现
面向对象设计原则
单一职责原则(SRP, Single Responsibility Principle)
- 定义:一个类(或模块、方法)应该只有一个引起它变化的原因,即只承担一种职责
- 核心思想:通过职责分离,降低类的复杂度,避免修改一处代码影响多个功能
- 应用场景:当类的方法明显属于不同领域(如业务逻辑、数据持久化、日志记录)时;避免“上帝类”,即一个类实现过多功能
开闭原则(OCP, Open-Closed Principle)
- 定义:软件实体(类、模块、函数)应对扩展开放,对修改关闭
- 核心思想:通过抽象和继承/组合,允许在不修改现有代码的情况下扩展功能
- 应用场景:功能需要频繁扩展(如支付方式、日志输出类型);使用策略模式、工厂模式等实现OCP
里氏替换原则(LSP, Liskov Substitution Principle)
- 定义:子类必须能够替换其父类,且替换后程序的行为不变
- 核心思想:继承关系应基于行为的一致性,而非单纯复用代码
- 应用场景:设计继承体系时,确保子类不改变父类的核心行为;优先使用组合而非继承(如装饰器模式)
接口隔离原则(ISP, Interface Segregation Principle)
-
定义:客户端不应被迫依赖它不使用的接口
-
核心思想:将臃肿的接口拆分为更小、更具体的接口,减少不必要的耦合
-
应用场景
- 避免“胖接口”(如Java的
java.util.Properties
继承自Hashtable
,但许多方法无用) - 使用适配器模式或门面模式隔离接口。
- 避免“胖接口”(如Java的
依赖倒置原则(DIP, Dependency Inversion Principle)
- 定义:高层模块不应依赖低层模块,二者都应依赖抽象;抽象不应依赖细节,细节应依赖抽象
- 核心思想:通过依赖注入(DI)或工厂模式解耦具体实现
- 应用场景:需要替换底层实现(如更换数据库、日志框架);使用Spring框架的依赖注入或策略模式实现DIP
第二部分 设计模式详解
创建型模式
单例模式(Singleton)
-
定义:确保一个类只有一个实例,并提供全局访问点
-
核心问题:如何避免重复创建对象(如数据库连接池、配置管理器);如何控制全局共享资源的访问
-
应用场景:全局配置管理类;日志记录器、线程池;缓存、计数器等共享资源
-
饿汉式:类加载时立即初始化(线程安全,但可能浪费资源)
public class Singleton { private static final Singleton INSTANCE = new Singleton(); private Singleton() {} // 私有构造 public static Singleton getInstance() { return INSTANCE; } }
-
懒汉式(双重校验锁) :延迟初始化且线程安全
public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
-
静态内部类:利用类加载机制保证线程安全
public class Singleton { private Singleton() {} private static class Holder { static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return Holder.INSTANCE; } }
工厂方法模式(Factory Method)
-
定义:定义一个创建对象的接口,但让子类决定实例化哪个具体类
-
核心思想:将对象的创建延迟到子类,实现扩展性;符合开闭原则(新增产品只需新增工厂子类)
-
结构
- 抽象工厂接口(定义创建方法)
- 具体工厂类(实现创建逻辑)
- 抽象产品接口(定义产品行为)
- 具体产品类(实现产品功能)
-
应用场景:跨平台UI组件库(不同操作系统生成不同风格的控件);数据库驱动程序的创建(如MySQL vs PostgreSQL连接器)
-
代码示例
// 抽象产品 interface Button { void render(); } // 具体产品:Windows风格按钮 class WindowsButton implements Button { public void render() { System.out.println("Windows按钮渲染"); } } // 具体产品:Mac风格按钮 class MacButton implements Button { public void render() { System.out.println("Mac按钮渲染"); } } // 抽象工厂 interface GUIFactory { Button createButton(); } // 具体工厂:Windows工厂 class WindowsFactory implements GUIFactory { public Button createButton() { return new WindowsButton(); } } // 具体工厂:Mac工厂 class MacFactory implements GUIFactory { public Button createButton() { return new MacButton(); } } // 客户端代码 public class Client { public static void main(String[] args) { GUIFactory factory = new MacFactory(); // 根据配置选择工厂 Button button = factory.createButton(); button.render(); // 输出:Mac按钮渲染 } }
抽象工厂模式(Abstract Factory)
-
定义:提供一个接口,用于创建相关或依赖对象的家族,而无需指定具体类
-
工厂方法:针对单一产品等级结构
-
抽象工厂:针对多个产品等级结构(如UI库中的按钮、文本框、滚动条等)
-
应用场景:跨平台UI库(保证同一家族的控件风格一致);数据库访问层(统一生成连接、命令、适配器等对象)
-
代码示例
// 抽象产品族:按钮、文本框 interface Button { void render(); } interface TextField { void input(); } // Mac产品族 class MacButton implements Button { public void render() { System.out.println("Mac按钮"); } } class MacTextField implements TextField { public void input() { System.out.println("Mac文本框输入"); } } // Windows产品族 class WindowsButton implements Button { /*...*/ } class WindowsTextField implements TextField { /*...*/ } // 抽象工厂接口 interface GUIFactory { Button createButton(); TextField createTextField(); } // 具体工厂:Mac工厂 class MacFactory implements GUIFactory { public Button createButton() { return new MacButton(); } public TextField createTextField() { return new MacTextField(); } } // 客户端代码 public class Client { public static void main(String[] args) { GUIFactory factory = new MacFactory(); Button button = factory.createButton(); TextField textField = factory.createTextField(); button.render(); // 输出:Mac按钮 textField.input(); // 输出:Mac文本框输入 } }
建造者模式(Builder)
-
定义:将复杂对象的构造过程与表示分离,使得同样的构建过程可以创建不同的表示
-
核心思想:分步骤构造对象(如配置可选参数、处理默认值);避免构造函数参数爆炸(尤其是可选参数多时)
-
结构
- Builder接口:定义构建步骤
- 具体Builder类:实现构建逻辑
- Director类(可选):指导构建过程(封装构建顺序)
- Product类:最终构建的复杂对象
-
应用场景
- 创建包含多个组件的复杂对象(如XML解析器、SQL查询构造器)
- 需要生成不同表示的对象(如同一数据导出为PDF、Excel格式)
- 可选参数较多的对象构造(替代重叠构造器或JavaBean模式)
-
代码示例
// 产品:计算机 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; } } // 抽象Builder interface ComputerBuilder { void buildCpu(); void buildRam(); void buildStorage(); Computer getResult(); } // 具体Builder:游戏电脑 class GamingComputerBuilder implements ComputerBuilder { private Computer computer = new Computer(); public void buildCpu() { computer.setCpu("i9-13900K"); } public void buildRam() { computer.setRam("32GB DDR5"); } public void buildStorage() { computer.setStorage("2TB NVMe SSD"); } public Computer getResult() { return computer; } } // Director:封装构建流程 class Director { public Computer construct(ComputerBuilder builder) { builder.buildCpu(); builder.buildRam(); builder.buildStorage(); return builder.getResult(); } } // 客户端代码 public class Client { public static void main(String[] args) { Director director = new Director(); ComputerBuilder builder = new GamingComputerBuilder(); Computer computer = director.construct(builder); } }
原型模式(Prototype)
-
定义:通过复制现有对象来创建新对象,而非通过
new
实例化 -
核心思想:利用对象克隆避免重复初始化(尤其是构造成本高的对象);支持动态添加或删除原型实例
-
实现方式
- 浅拷贝:复制基本类型字段,引用类型字段共享(Java默认
clone()
方法) - 深拷贝:递归复制所有引用对象(需手动实现或序列化)
- 浅拷贝:复制基本类型字段,引用类型字段共享(Java默认
-
应用场景:对象创建成本高(如数据库查询结果缓存);需要动态生成对象副本;需要隔离对象与其副本的状态修改
-
代码示例
// 原型接口 interface Prototype extends Cloneable { Prototype clone() throws CloneNotSupportedException; } // 具体原型:简历 class Resume implements Prototype { private String name; private String workExperience; public Resume(String name) { this.name = name; // 模拟耗时初始化(如从数据库加载工作经历) this.workExperience = loadWorkExperienceFromDB(); } private String loadWorkExperienceFromDB() { // 假设此操作耗时较长 return "工作经验数据..."; } @Override public Resume clone() throws CloneNotSupportedException { return (Resume) super.clone(); // 浅拷贝 } } // 客户端代码 public class Client { public static void main(String[] args) throws Exception { Resume original = new Resume("张三"); Resume copy = original.clone(); // 避免重新执行耗时初始化 } }
创建型模式对比
单例 | 全局唯一实例 | 配置管理、资源池 | 限制实例数量 |
工厂方法 | 单个产品的灵活创建 | 跨平台UI控件 | 子类决定实例化类 |
抽象工厂 | 创建产品家族 | 跨风格UI组件库 | 生产多类相关对象 |
建造者 | 分步骤构建复杂对象 | 包含多部件的对象构造 | 分离构造过程与表示 |
原型 | 克隆已有对象避免重复初始化 | 高成本对象的快速复制 | 利用已有对象生成新实例 |
结构型模式
代理模式
-
定义:为对象提供一个代理,以控制对其的访问(如权限验证、延迟加载、日志记录等)
-
核心思想:在不修改原始对象的前提下,增强其功能;代理类与原始类实现同一接口,客户端无感知
-
结构
- Subject接口:定义代理和真实对象的共同行为
- RealSubject:真实业务逻辑的实现
- Proxy:代理类,持有RealSubject的引用,并在调用前后添加额外逻辑
-
应用场景:延迟加载(Lazy Initialization):如大型图片加载;访问控制:权限验证、防火墙代理;日志记录或性能监控
-
JDK代理
// 创建代理对象 public static Object createProxy(Object target) { return Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new LoggingProxy(target) ); } // LoggingProxy implements InvocationHandler 重写invoke方法
-
CGLIB代理(Code Generation Library)
// 1. 创建Enhancer实例 Enhancer enhancer = new Enhancer(); // 2. 设置父类(目标类) enhancer.setSuperclass(UserService.class); // 3. 设置回调(方法拦截器) enhancer.setCallback(new LogInterceptor()); // 4. 创建代理对象 UserService proxy = (UserService) enhancer.create(); // 5. 通过代理对象调用方法 proxy.save(); proxy.finalMethod(); // final方法不会被代理 // LogInterceptor implements MethodInterceptor 重写intercept方法
-
代码示例:
// 接口:文件加载器 interface FileLoader { String loadFile(String filename); } // 真实实现:远程文件加载 class RemoteFileLoader implements FileLoader { public String loadFile(String filename) { System.out.println("从远程服务器加载文件:" + filename); return "文件内容"; } } // 代理:缓存代理 class CachedFileLoaderProxy implements FileLoader { private RemoteFileLoader realLoader; private Map<String, String> cache = new HashMap<>(); public String loadFile(String filename) { if (cache.containsKey(filename)) { System.out.println("从缓存加载文件:" + filename); return cache.get(filename); } else { realLoader = new RemoteFileLoader(); String content = realLoader.loadFile(filename); cache.put(filename, content); return content; } } } // 客户端 public class Client { public static void main(String[] args) { FileLoader loader = new CachedFileLoaderProxy(); loader.loadFile("data.txt"); // 第一次从远程加载 loader.loadFile("data.txt"); // 第二次从缓存加载 } }
桥接模式
-
定义:将抽象部分与实现部分分离,使二者可以独立变化
-
核心思想:通过组合替代继承,避免类爆炸(如多维度变化时的组合问题)
-
结构
- Abstraction:抽象类的顶层接口
- RefinedAbstraction:扩展抽象类
- Implementor:实现类接口
- ConcreteImplementor:具体实现
-
应用场景:UI框架中跨平台渲染(如不同操作系统下的按钮绘制);设备驱动与应用程序的解耦
-
代码示例
// 实现接口:绘图引擎 interface DrawingAPI { void drawCircle(double x, double y, double radius); } // 具体实现:OpenGL绘图 class OpenGLDrawingAPI implements DrawingAPI { public void drawCircle(double x, double y, double radius) { System.out.printf("OpenGL画圆:(%f, %f), 半径%f\n", x, y, radius); } } // 抽象类:形状 abstract class Shape { protected DrawingAPI drawingAPI; protected Shape(DrawingAPI drawingAPI) { this.drawingAPI = drawingAPI; } public abstract void draw(); } // 扩展抽象:圆形 class Circle extends Shape { private double x, y, radius; public Circle(double x, double y, double r, DrawingAPI api) { super(api); this.x = x; this.y = y; this.radius = r; } public void draw() { drawingAPI.drawCircle(x, y, radius); } } // 客户端 public class Client { public static void main(String[] args) { DrawingAPI opengl = new OpenGLDrawingAPI(); Shape circle = new Circle(10, 20, 5, opengl); circle.draw(); // 输出:OpenGL画圆... } }
装饰器模式
-
定义:动态地为对象添加职责,且比继承更灵活
-
核心思想:通过组合和委托,实现功能的叠加;装饰器类与被装饰对象实现相同接口
-
应用场景:动态添加功能(如日志、缓存、压缩);避免子类膨胀(如Java I/O流中的
BufferedInputStream
) -
代码示例
// 基础接口:数据源 interface DataSource { void writeData(String data); String readData(); } // 具体实现:文件数据源 class FileDataSource implements DataSource { public void writeData(String data) { /* 写入文件 */ } public String readData() { /* 读取文件 */ return "data"; } } // 装饰器基类 abstract class DataSourceDecorator implements DataSource { protected DataSource wrappee; public DataSourceDecorator(DataSource source) { this.wrappee = source; } } // 具体装饰器:加密装饰器 class EncryptionDecorator extends DataSourceDecorator { public EncryptionDecorator(DataSource source) { super(source); } public void writeData(String data) { String encrypted = encrypt(data); wrappee.writeData(encrypted); } public String readData() { String data = wrappee.readData(); return decrypt(data); } private String encrypt(String data) { /* 加密逻辑 */ return data; } private String decrypt(String data) { /* 解密逻辑 */ return data; } } // 客户端 public class Client { public static void main(String[] args) { DataSource source = new FileDataSource(); DataSource encryptedSource = new EncryptionDecorator(source); encryptedSource.writeData("敏感数据"); // 自动加密后写入 } }
适配器模式
-
定义:将一个接口转换为客户端期望的另一个接口,解决接口不兼容问题
-
实现方式
- 类适配器:通过继承实现适配(多语言中可能不支持)
- 对象适配器:通过组合实现适配(更灵活)
-
应用场景:整合遗留代码或第三方库;统一多个类的接口(如不同支付网关的适配)
-
与桥接模式区别:适配器解决已有接口不兼容,桥接模式提前设计抽象与实现分离
-
代码示例
// 旧系统:第三方日志接口 class LegacyLogger { void logMessage(String message, int severity) { System.out.println("Legacy日志: " + message + ", 级别:" + severity); } } // 新系统要求的日志接口 interface NewLogger { void info(String message); void error(String message); } // 适配器类 class LoggerAdapter implements NewLogger { private LegacyLogger legacyLogger; public LoggerAdapter(LegacyLogger logger) { this.legacyLogger = logger; } public void info(String message) { legacyLogger.logMessage(message, 1); } public void error(String message) { legacyLogger.logMessage(message, 3); } } // 客户端 public class Client { public static void main(String[] args) { NewLogger logger = new LoggerAdapter(new LegacyLogger()); logger.info("系统启动"); // 转换为旧接口的logMessage调用 } }
门面模式
-
定义:为复杂子系统提供一个统一的高层接口,简化客户端调用
-
应用场景:简化复杂系统调用流程(如电商下单);为外部系统提供易用的API入口
-
代码示例
// 子系统:订单处理 class InventorySystem { boolean checkStock(String productId) { /* 检查库存 */ return true; } } class PaymentSystem { boolean processPayment(double amount) { /* 处理支付 */ return true; } } class ShippingSystem { void scheduleDelivery(String address) { /* 安排配送 */ } } // 门面类 class OrderFacade { private InventorySystem inventory = new InventorySystem(); private PaymentSystem payment = new PaymentSystem(); private ShippingSystem shipping = new ShippingSystem(); public boolean placeOrder(String productId, double amount, String address) { if (!inventory.checkStock(productId)) return false; if (!payment.processPayment(amount)) return false; shipping.scheduleDelivery(address); return true; } } // 客户端 public class Client { public static void main(String[] args) { OrderFacade facade = new OrderFacade(); facade.placeOrder("123", 99.9, "北京"); } }
组合模式
-
定义:以树形结构组合对象,使客户端统一处理单个对象和对象组合
-
结构
- Component接口:定义叶子和容器的共同行为
- Leaf:叶子节点(无子节点)
- Composite:容器节点(可包含子Component)
-
应用场景:文件系统目录结构;UI组件树(如窗口包含面板、按钮等);组织架构管理(部门与员工)
-
代码示例
// Component接口 interface FileSystemComponent { void display(); } // 叶子:文件 class File implements FileSystemComponent { private String name; public File(String name) { this.name = name; } public void display() { System.out.println("文件:" + name); } } // 容器:文件夹 class Folder implements FileSystemComponent { private String name; private List<FileSystemComponent> children = new ArrayList<>(); public Folder(String name) { this.name = name; } public void add(FileSystemComponent comp) { children.add(comp); } public void display() { System.out.println("文件夹:" + name); for (FileSystemComponent comp : children) { comp.display(); } } } // 客户端 public class Client { public static void main(String[] args) { Folder root = new Folder("根目录"); root.add(new File("a.txt")); Folder subDir = new Folder("子文件夹"); subDir.add(new File("b.doc")); root.add(subDir); root.display(); // 递归显示所有子节点 } }
享元模式
-
定义:通过共享技术高效支持大量细粒度对象
-
核心思想:分离内部状态(可共享)与外部状态(不可共享);使用工厂缓存共享对象
-
应用场景:游戏中的大量重复对象(如子弹、树木);文字编辑器中的字符对象;线程池、数据库连接池
-
代码示例
// 享元对象:棋子 class ChessPiece { private String color; // 内部状态(可共享) public ChessPiece(String color) { this.color = color; } public void draw(int x, int y) { // 外部状态由客户端传递 System.out.printf("%s棋子放置在(%d, %d)\n", color, x, y); } } // 享元工厂 class ChessPieceFactory { private static Map<String, ChessPiece> pieces = new HashMap<>(); public static ChessPiece getPiece(String color) { if (!pieces.containsKey(color)) { pieces.put(color, new ChessPiece(color)); } return pieces.get(color); } } // 客户端 public class Client { public static void main(String[] args) { ChessPiece white1 = ChessPieceFactory.getPiece("白"); ChessPiece white2 = ChessPieceFactory.getPiece("白"); // 复用同一对象 white1.draw(1, 2); white2.draw(3, 4); } }
结构型模式对比
代理 | 控制对象访问 | 权限验证、延迟加载 | 增强访问控制 |
桥接 | 分离抽象与实现 | 多维度变化的系统 | 避免继承爆炸 |
装饰器 | 动态添加职责 | 功能叠加(如日志、加密) | 透明增强功能 |
适配器 | 接口转换 | 整合遗留系统 | 解决接口不兼容 |
门面 | 简化复杂子系统调用 | 提供统一API入口 | 封装内部复杂性 |
组合 | 统一处理树形结构 | 文件系统、UI组件树 | 递归组合对象 |
享元 | 高效共享细粒度对象 | 大量重复对象的场景 | 分离内部/外部状态 |
行为型模式
观察者模式
-
定义:定义对象间的一对多依赖,当一个对象状态改变时,自动通知所有依赖对象
-
核心思想:解耦发布者(Subject)与订阅者(Observer);支持动态添加或移除观察者
-
结构:
- Subject接口:管理观察者列表,提供注册/注销方法
- ConcreteSubject:具体主题,维护状态并触发通知
- Observer接口:定义更新方法
- ConcreteObserver:实现更新逻辑
-
应用场景:事件驱动系统(如GUI按钮点击事件);实时数据推送(股票价格更新、新闻订阅);分布式系统中的服务状态通知
-
代码示例
// 主题接口 interface NewsPublisher { void addSubscriber(Subscriber s); void removeSubscriber(Subscriber s); void notifySubscribers(String news); } // 具体主题:新闻发布中心 class NewsCenter implements NewsPublisher { private List<Subscriber> subscribers = new ArrayList<>(); public void addSubscriber(Subscriber s) { subscribers.add(s); } public void removeSubscriber(Subscriber s) { subscribers.remove(s); } public void notifySubscribers(String news) { for (Subscriber s : subscribers) { s.update(news); } } public void publishNews(String news) { System.out.println("发布新闻:" + news); notifySubscribers(news); } } // 观察者接口 interface Subscriber { void update(String news); } // 具体观察者:用户 class User implements Subscriber { private String name; public User(String name) { this.name = name; } public void update(String news) { System.out.println(name + " 收到新闻:" + news); } } // 客户端 public class Client { public static void main(String[] args) { NewsCenter center = new NewsCenter(); center.addSubscriber(new User("张三")); center.addSubscriber(new User("李四")); center.publishNews("今日头条:设计模式之美发布!"); } }
模板方法模式
-
定义:在父类中定义算法的骨架,将某些步骤延迟到子类实现
-
核心思想:通过继承实现代码复用,控制子类扩展点
-
应用场景:框架中的流程标准化(如Spring的JdbcTemplate);算法步骤固定但部分实现可变(如不同格式的报表生成)
-
代码示例
// 抽象类:数据导出模板 abstract class DataExporter { // 模板方法(final防止子类覆盖) public final void export() { fetchData(); processData(); saveToFile(); } protected abstract void fetchData(); protected abstract void processData(); private void saveToFile() { System.out.println("保存数据到文件"); } } // 具体子类:CSV导出 class CSVExporter extends DataExporter { protected void fetchData() { System.out.println("从数据库加载数据"); } protected void processData() { System.out.println("将数据转换为CSV格式"); } } // 客户端 public class Client { public static void main(String[] args) { DataExporter exporter = new CSVExporter(); exporter.export(); } }
策略模式
-
定义:定义算法族,封装每个算法,使其可互相替换
-
核心思想:将算法与使用算法的客户端解耦
-
应用场景:多种算法切换(排序算法、支付方式);需要动态选择行为的系统
-
代码示例
// 策略接口:支付方式 interface PaymentStrategy { void pay(double amount); } // 具体策略:支付宝支付 class AlipayStrategy implements PaymentStrategy { public void pay(double amount) { System.out.println("支付宝支付:" + amount + "元"); } } // 上下文类:订单 class Order { private PaymentStrategy strategy; public void setPaymentStrategy(PaymentStrategy strategy) { this.strategy = strategy; } public void checkout(double amount) { strategy.pay(amount); } } // 客户端 public class Client { public static void main(String[] args) { Order order = new Order(); order.setPaymentStrategy(new AlipayStrategy()); order.checkout(100.0); } }
责任链模式
-
定义:将请求的发送者与接收者解耦,使多个对象都有机会处理请求
-
核心思想:请求沿处理链传递,直到被处理或链结束
-
应用场景:多级审批流程(如请假审批);过滤器链(如Web请求处理)
-
代码示例
// 处理器接口 interface Handler { void handleRequest(Request request); void setNext(Handler next); } // 具体处理器:日志记录 class LoggerHandler implements Handler { private Handler next; public void setNext(Handler next) { this.next = next; } public void handleRequest(Request request) { System.out.println("记录请求日志:" + request.getData()); if (next != null) { next.handleRequest(request); } } } // 客户端构建责任链 public class Client { public static void main(String[] args) { Handler chain = new LoggerHandler(); chain.setNext(new AuthHandler()); chain.handleRequest(new Request("敏感数据")); } }
状态模式
-
定义:允许对象在其内部状态改变时改变行为
-
应用场景:订单状态流转;游戏角色行为随状态变化
-
代码示例
// 状态接口 interface OrderState { void next(Order order); } // 具体状态:已下单 class PlacedState implements OrderState { public void next(Order order) { System.out.println("订单已下单,转为已支付状态"); order.setState(new PaidState()); } } // 上下文类:订单 class Order { private OrderState state; public Order() { state = new PlacedState(); } public void nextState() { state.next(this); } void setState(OrderState state) { this.state = state; } }
迭代器模式
-
定义:提供一种方法顺序访问聚合对象的元素,而无需暴露其内部表示
-
应用场景:集合类的遍历;屏蔽不同数据结构(数组、链表)的遍历差异
-
代码示例
interface Iterator<T> { boolean hasNext(); T next(); } class ListIterator<T> implements Iterator<T> { private List<T> list; private int index = 0; public ListIterator(List<T> list) { this.list = list; } public boolean hasNext() { return index < list.size(); } public T next() { return list.get(index++); } }
访问者模式
-
定义:将算法与对象结构分离,允许在不修改对象结构的情况下添加新操作。
-
应用场景:编译器语法树分析;复杂对象结构的统计操作
-
代码示例
interface Visitor { void visit(ElementA element); void visit(ElementB element); } class ConcreteVisitor implements Visitor { public void visit(ElementA element) { System.out.println("处理A元素"); } public void visit(ElementB element) { System.out.println("处理B元素"); } }
备忘录模式
-
定义:在不破坏封装性的前提下,捕获对象的内部状态,并在需要时恢复该状态
-
核心思想:分离对象状态的保存与恢复逻辑,支持撤销(Undo)或历史记录功能
-
结构
- Originator(原发器) :需要保存状态的对象
- Memento(备忘录) :存储Originator的内部状态
- Caretaker(管理者) :负责保存和恢复备忘录
-
应用场景:文本编辑器的撤销/重做功能;游戏存档与读档;事务回滚机制
-
代码示例
// 原发器:文本编辑器 class TextEditor { private String content; public void write(String text) { this.content = text; } public String getContent() { return content; } // 创建备忘录 public TextMemento save() { return new TextMemento(content); } // 恢复备忘录 public void restore(TextMemento memento) { this.content = memento.getSavedContent(); } } // 备忘录:保存状态 class TextMemento { private final String content; public TextMemento(String content) { this.content = content; } public String getSavedContent() { return content; } } // 管理者:管理历史记录 class History { private Stack<TextMemento> stack = new Stack<>(); public void push(TextMemento memento) { stack.push(memento); } public TextMemento pop() { return stack.pop(); } } // 客户端 public class Client { public static void main(String[] args) { TextEditor editor = new TextEditor(); History history = new History(); editor.write("Hello"); history.push(editor.save()); // 保存状态 editor.write("Hello World"); editor.restore(history.pop()); // 撤销到上一状态 System.out.println(editor.getContent()); // 输出:Hello } }
命令模式
- 定义:将请求封装为对象,以便参数化客户端请求,支持请求排队、日志记录或撤销操作
- 核心思想:解耦请求的发送者与接收者,将请求的调用与执行分离
-
结构:
- Command接口:定义执行方法(如
execute()
)。
- ConcreteCommand:实现具体命令,绑定接收者与动作。
- Invoker(调用者) :触发命令执行(如按钮、遥控器)。
- Receiver(接收者) :实际执行请求的对象。
- Command接口:定义执行方法(如
-
应用场景:GUI按钮或菜单操作;任务队列、日志记录(支持重做);支持撤销/重做的系统(如绘图软件)
-
代码示例
// 接收者:电灯 class Light { public void on() { System.out.println("电灯打开"); } public void off() { System.out.println("电灯关闭"); } } // 命令接口 interface Command { void execute(); } // 具体命令:开灯命令 class LightOnCommand implements Command { private Light light; public LightOnCommand(Light light) { this.light = light; } public void execute() { light.on(); } } // 调用者:遥控器按钮 class RemoteControl { private Command command; public void setCommand(Command command) { this.command = command; } public void pressButton() { command.execute(); } } // 客户端 public class Client { public static void main(String[] args) { Light light = new Light(); Command lightOn = new LightOnCommand(light); RemoteControl remote = new RemoteControl(); remote.setCommand(lightOn); remote.pressButton(); // 输出:电灯打开 } }
解释器模式
- 定义:定义语言的文法,并提供一个解释器来处理该语言中的句子
- 核心思想:将特定类型的问题表示为语言规则,通过解释器执行解析
-
结构:
- 抽象表达式(Expression) :声明解释操作的接口。
- 终结符表达式(TerminalExpression) :处理语言中的基本元素(如变量、常量)
- 非终结符表达式(NonterminalExpression) :处理语言中的组合规则(如运算、逻辑判断)
- 上下文(Context) :包含解释器需要的全局信息
-
应用场景:SQL、正则表达式解析;数学公式计算器;领域特定语言(DSL)的实现
-
代码示例
// 抽象表达式 interface Expression { boolean interpret(Context context); } // 终结符表达式:变量 class Variable implements Expression { private String name; public Variable(String name) { this.name = name; } public boolean interpret(Context context) { return context.get(this.name); } } // 非终结符表达式:逻辑与 class And implements Expression { private Expression left; private Expression right; public And(Expression left, Expression right) { this.left = left; this.right = right; } public boolean interpret(Context context) { return left.interpret(context) && right.interpret(context); } } // 上下文:存储变量值 class Context { private Map<String, Boolean> variables = new HashMap<>(); public void set(String name, boolean value) { variables.put(name, value); } public boolean get(String name) { return variables.get(name); } } // 客户端 public class Client { public static void main(String[] args) { Context context = new Context(); context.set("A", true); context.set("B", false); Expression expr = new And(new Variable("A"), new Variable("B")); System.out.println(expr.interpret(context)); // 输出:false } }
中介者模式
-
定义:定义一个中介对象来封装一组对象间的交互,使其耦合度降低,且可以独立改变它们之间的交互
-
核心思想:将网状的对象交互改为星型结构,中介者作为协调中心
-
结构:
- Mediator接口:定义同事对象通信的方法
- ConcreteMediator:协调各同事对象的交互
- Colleague(同事类) :每个同事类只知道中介者,不直接交互
-
应用场景:GUI组件间的通信(如对话框中的输入框);多玩家游戏中的角色互动;航班调度系统(协调飞机、跑道、塔台)
-
代码示例
// 中介者接口 interface ChatMediator { void sendMessage(String msg, User user); void addUser(User user); } // 具体中介者:聊天室 class ChatRoom implements ChatMediator { private List<User> users = new ArrayList<>(); public void addUser(User user) { users.add(user); } public void sendMessage(String msg, User sender) { for (User user : users) { if (user != sender) { // 不发送给发送者自己 user.receive(msg); } } } } // 同事类:用户 abstract class User { protected ChatMediator mediator; protected String name; public User(ChatMediator mediator, String name) { this.mediator = mediator; this.name = name; } public abstract void send(String msg); public abstract void receive(String msg); } class ChatUser extends User { public ChatUser(ChatMediator mediator, String name) { super(mediator, name); } public void send(String msg) { System.out.println(name + " 发送消息:" + msg); mediator.sendMessage(msg, this); } public void receive(String msg) { System.out.println(name + " 收到消息:" + msg); } } // 客户端 public class Client { public static void main(String[] args) { ChatMediator chatRoom = new ChatRoom(); User alice = new ChatUser(chatRoom, "Alice"); User bob = new ChatUser(chatRoom, "Bob"); chatRoom.addUser(alice); chatRoom.addUser(bob); alice.send("你好,Bob!"); // 输出: // Alice 发送消息:你好,Bob! // Bob 收到消息:你好,Bob! } }
行为型模式对比
观察者 | 一对多事件通知 | 实时数据推送、GUI事件 |
策略 | 算法灵活替换 | 支付方式、排序算法选择 |
状态 | 行为随状态改变 | 订单状态机、游戏角色行为 |
责任链 | 请求传递处理链 | 审批流程、过滤器链 |
访问者 | 分离数据结构与操作 | 语法树分析、报表生成 |
备忘录 | 保存与恢复对象状态 | 撤销操作、游戏存档 |
命令 | 封装请求为对象,支持解耦与扩展 | 任务队列、GUI操作管理 |
解释器 | 解析特定语法规则 | SQL解析、公式计算 |
中介者 | 集中管理对象间交互 | 聊天室、复杂UI组件协调 |