23种设计模式全解析:从理论到实践

管理员
> 设计模式不是代码,而是解决方案的模板。掌握它,让你的代码更具可维护性、可扩展性和灵活性。 --- ## 前言 在软件开发中,我们经常遇到相似的问题。设计模式就是前辈们在解决这些问题时总结出的最佳实践。它们不是可以直接套用的代码,而是经过验证的解决方案模板。 GoF(Gang of Four)在1994年提出了23种经典设计模式,分为三大类: 1. **创建型模式(5种)**:处理对象的创建机制 2. **结构型模式(7种)**:处理类或对象的组合 3. **行为型模式(11种)**:处理对象之间的通信和职责分配 --- **示例** **创建型模式(5种)** - 单例模式:3种实现方式 - 工厂方法模式:完整的接口和实现类结构 - 抽象工厂模式:跨平台UI组件的完整示例 - 建造者模式:使用链式调用的Builder模式 - 原型模式:实现Cloneable接口的深拷贝示例 **结构型模式(7种)** - 适配器模式:提供类适配器和对象适配器两种实现 - 桥接模式:形状与颜色分离的经典示例 - 组合模式:文件系统的树形结构实现 - 装饰器模式:咖啡加料的动态装饰示例 - 外观模式:电脑启动的简化接口 - 享元模式:图形对象共享的内存优化 - 代理模式:提供静态代理和动态代理两种实现 **行为型模式(11种)** - 责任链模式:审批流程的链式处理 - 命令模式:支持撤销功能的遥控器示例 - 解释器模式:布尔表达式求值的完整实现 - 迭代器模式:自定义迭代器和聚合接口 - 中介者模式:聊天室的消息转发机制 - 备忘录模式:游戏存档的状态保存与恢复 - 观察者模式:提供自定义实现和Java内置Observer两种方式 - 状态模式:状态自动流转的上下文管理 - 策略模式:多种支付方式的灵活切换 - 模板方法模式:数据处理的算法骨架 - 访问者模式:购物车结算的不同操作 --- ## 一、创建型模式 ### 1. 单例模式(Singleton) **核心思想**:确保一个类只有一个实例,并提供全局访问点。 **适用场景**: - 数据库连接池 - 日志记录器 - 配置管理器 **代码示例(Java - 饿汉式)**: ```java public class Singleton { // 饿汉式:类加载时就创建实例 private static final Singleton INSTANCE = new Singleton(); // 私有构造函数,防止外部实例化 private Singleton() {} // 提供全局访问点 public static Singleton getInstance() { return INSTANCE; } public void doSomething() { System.out.println("Singleton is doing something."); } } ``` **代码示例(Java - 懒汉式 + 双重检查锁)**: ```java public class Singleton { // volatile 防止指令重排序 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; } } ``` **代码示例(Java - 静态内部类)**: ```java public class Singleton { private Singleton() {} // 静态内部类,利用类加载机制保证线程安全 private static class Holder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return Holder.INSTANCE; } } ``` **优点**:减少内存开销,避免对资源的多重占用 **缺点**:难以扩展,不符合单一职责原则 --- ### 2. 工厂方法模式(Factory Method) **核心思想**:定义一个创建对象的接口,让子类决定实例化哪个类。 **适用场景**: - 日志记录器(文件日志、数据库日志) - 数据库连接(MySQL、PostgreSQL、Oracle) **代码示例(Java)**: ```java // 产品接口 interface Logger { void log(String message); } // 具体产品 class FileLogger implements Logger { @Override public void log(String message) { System.out.println("File Logger: " + message); } } class DatabaseLogger implements Logger { @Override public void log(String message) { System.out.println("Database Logger: " + message); } } // 工厂接口 interface LoggerFactory { Logger createLogger(); } // 具体工厂 class FileLoggerFactory implements LoggerFactory { @Override public Logger createLogger() { return new FileLogger(); } } class DatabaseLoggerFactory implements LoggerFactory { @Override public Logger createLogger() { return new DatabaseLogger(); } } // 使用示例 public class FactoryMethodDemo { public static void main(String[] args) { LoggerFactory factory = new FileLoggerFactory(); Logger logger = factory.createLogger(); logger.log("This is a test message."); } } ``` **优点**:符合开闭原则,扩展性好 **缺点**:类的数量增加,系统复杂度提高 --- ### 3. 抽象工厂模式(Abstract Factory) **核心思想**:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。 **适用场景**: - 跨平台UI组件(Windows风格、Mac风格) - 不同数据库的访问层 **代码示例(Java)**: ```java // 抽象产品A interface Button { void click(); } // 抽象产品B interface Checkbox { void check(); } // 具体产品 - Windows风格 class WindowsButton implements Button { @Override public void click() { System.out.println("Windows Button clicked."); } } class WindowsCheckbox implements Checkbox { @Override public void check() { System.out.println("Windows Checkbox checked."); } } // 具体产品 - Mac风格 class MacButton implements Button { @Override public void click() { System.out.println("Mac Button clicked."); } } class MacCheckbox implements Checkbox { @Override public void check() { System.out.println("Mac Checkbox checked."); } } // 抽象工厂 interface GUIFactory { Button createButton(); Checkbox createCheckbox(); } // 具体工厂 class WindowsFactory implements GUIFactory { @Override public Button createButton() { return new WindowsButton(); } @Override public Checkbox createCheckbox() { return new WindowsCheckbox(); } } class MacFactory implements GUIFactory { @Override public Button createButton() { return new MacButton(); } @Override public Checkbox createCheckbox() { return new MacCheckbox(); } } // 使用示例 public class AbstractFactoryDemo { public static void main(String[] args) { GUIFactory factory = new WindowsFactory(); Button button = factory.createButton(); Checkbox checkbox = factory.createCheckbox(); button.click(); checkbox.check(); } } ``` **优点**:隔离具体类的生成,保证产品族的一致性 **缺点**:扩展产品族困难,抽象层增加复杂度 --- ### 4. 建造者模式(Builder) **核心思想**:将复杂对象的构建与表示分离,使同样的构建过程可以创建不同的表示。 **适用场景**: - 构建复杂的HTML页面 - 创建具有多个配置项的对象 **代码示例(Java)**: ```java // 产品类 class Computer { private String cpu; private String ram; private String storage; private String gpu; private Computer(Builder builder) { this.cpu = builder.cpu; this.ram = builder.ram; this.storage = builder.storage; this.gpu = builder.gpu; } @Override public String toString() { return "Computer{" + "cpu='" + cpu + '\'' + ", ram='" + ram + '\'' + ", storage='" + storage + '\'' + ", gpu='" + gpu + '\'' + '}'; } // 建造者 public static class Builder { private String cpu; private String ram; private String storage; private String gpu; public Builder cpu(String cpu) { this.cpu = cpu; return this; } public Builder ram(String ram) { this.ram = ram; return this; } public Builder storage(String storage) { this.storage = storage; return this; } public Builder gpu(String gpu) { this.gpu = gpu; return this; } public Computer build() { return new Computer(this); } } } // 使用示例 public class BuilderDemo { public static void main(String[] args) { Computer computer = new Computer.Builder() .cpu("Intel i9") .ram("32GB DDR5") .storage("1TB NVMe SSD") .gpu("RTX 4090") .build(); System.out.println(computer); } } ``` **优点**:构建过程清晰,可以控制构建细节 **缺点**:产品必须有共同点,范围有限制 --- ### 5. 原型模式(Prototype) **核心思想**:通过复制现有对象来创建新对象,而不是通过new。 **适用场景**: - 创建成本较高的对象 - 需要保存对象状态的场景 **代码示例(Java)**: ```java // 原型接口 interface Prototype extends Cloneable { Prototype clone(); } // 具体原型 class Document implements Prototype { private String title; private String content; private String author; public Document(String title, String content, String author) { this.title = title; this.content = content; this.author = author; } // 深拷贝 @Override public Document clone() { try { Document cloned = (Document) super.clone(); // 如果有引用类型,需要单独克隆 return cloned; } catch (CloneNotSupportedException e) { throw new RuntimeException("Clone not supported", e); } } // Getters and Setters public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } @Override public String toString() { return "Document{title='" + title + "', content='" + content + "', author='" + author + "'}"; } } // 使用示例 public class PrototypeDemo { public static void main(String[] args) { Document original = new Document("设计模式", "原型模式示例", "张三"); Document cloned = original.clone(); cloned.setTitle("设计模式 - 副本"); System.out.println("Original: " + original); System.out.println("Cloned: " + cloned); } } ``` **优点**:提高性能,逃避构造函数约束 **缺点**:必须实现克隆方法,对深拷贝可能有问题 --- ## 二、结构型模式 ### 6. 适配器模式(Adapter) **核心思想**:将一个类的接口转换成客户希望的另一个接口。 **适用场景**: - 遗留系统的接口转换 - 第三方库的接口适配 **代码示例(Java - 类适配器)**: ```java // 目标接口 interface Target { void request(); } // 被适配者 class Adaptee { public void specificRequest() { System.out.println("Adaptee: specific request."); } } // 类适配器 class ClassAdapter extends Adaptee implements Target { @Override public void request() { specificRequest(); } } ``` **代码示例(Java - 对象适配器)**: ```java // 对象适配器 class ObjectAdapter implements Target { private Adaptee adaptee; public ObjectAdapter(Adaptee adaptee) { this.adaptee = adaptee; } @Override public void request() { adaptee.specificRequest(); } } // 使用示例 public class AdapterDemo { public static void main(String[] args) { Adaptee adaptee = new Adaptee(); Target adapter = new ObjectAdapter(adaptee); adapter.request(); } } ``` **优点**:提高类的复用性,灵活性好 **缺点**:过多使用会使系统混乱 --- ### 7. 桥接模式(Bridge) **核心思想**:将抽象部分与实现部分分离,使它们可以独立变化。 **适用场景**: - JDBC驱动程序 - 图形形状与颜色系统 **代码示例(Java)**: ```java // 实现接口 interface Color { void applyColor(); } // 具体实现 class RedColor implements Color { @Override public void applyColor() { System.out.println("Applying red color."); } } class BlueColor implements Color { @Override public void applyColor() { System.out.println("Applying blue color."); } } // 抽象类 abstract class Shape { protected Color color; public Shape(Color color) { this.color = color; } public abstract void draw(); } // 具体抽象 class Circle extends Shape { public Circle(Color color) { super(color); } @Override public void draw() { System.out.print("Drawing circle. "); color.applyColor(); } } class Square extends Shape { public Square(Color color) { super(color); } @Override public void draw() { System.out.print("Drawing square. "); color.applyColor(); } } // 使用示例 public class BridgeDemo { public static void main(String[] args) { Shape redCircle = new Circle(new RedColor()); Shape blueSquare = new Square(new BlueColor()); redCircle.draw(); blueSquare.draw(); } } ``` **优点**:分离抽象与实现,扩展能力强 **缺点**:增加系统复杂度 --- ### 8. 组合模式(Composite) **核心思想**:将对象组合成树形结构来表示"部分-整体"的层次结构。 **适用场景**: - 文件系统(文件和文件夹) - 组织架构图 **代码示例(Java)**: ```java import java.util.ArrayList; import java.util.List; // 组件接口 interface FileSystemNode { void display(); void add(FileSystemNode node); void remove(FileSystemNode node); } // 叶子节点 class File implements FileSystemNode { private String name; public File(String name) { this.name = name; } @Override public void display() { System.out.println("File: " + name); } @Override public void add(FileSystemNode node) { throw new UnsupportedOperationException("Cannot add to file."); } @Override public void remove(FileSystemNode node) { throw new UnsupportedOperationException("Cannot remove from file."); } } // 组合节点 class Directory implements FileSystemNode { private String name; private List children = new ArrayList<>(); public Directory(String name) { this.name = name; } @Override public void display() { System.out.println("Directory: " + name); for (FileSystemNode child : children) { child.display(); } } @Override public void add(FileSystemNode node) { children.add(node); } @Override public void remove(FileSystemNode node) { children.remove(node); } } // 使用示例 public class CompositeDemo { public static void main(String[] args) { File file1 = new File("file1.txt"); File file2 = new File("file2.txt"); Directory subDir = new Directory("subdirectory"); subDir.add(new File("file3.txt")); Directory rootDir = new Directory("root"); rootDir.add(file1); rootDir.add(file2); rootDir.add(subDir); rootDir.display(); } } ``` **优点**:定义了包含基本对象和组合对象的类层次结构 **缺点**:设计较复杂 --- ### 9. 装饰器模式(Decorator) **核心思想**:动态地给一个对象添加一些额外的职责。 **适用场景**: - Java I/O流 - 动态功能增强 **代码示例(Java)**: ```java // 组件接口 interface Coffee { double cost(); String description(); } // 具体组件 class SimpleCoffee implements Coffee { @Override public double cost() { return 10.0; } @Override public String description() { return "Simple Coffee"; } } // 装饰器基类 abstract class CoffeeDecorator implements Coffee { protected Coffee decoratedCoffee; public CoffeeDecorator(Coffee coffee) { this.decoratedCoffee = coffee; } @Override public double cost() { return decoratedCoffee.cost(); } @Override public String description() { return decoratedCoffee.description(); } } // 具体装饰器 class MilkDecorator extends CoffeeDecorator { public MilkDecorator(Coffee coffee) { super(coffee); } @Override public double cost() { return super.cost() + 2.0; } @Override public String description() { return super.description() + ", Milk"; } } class SugarDecorator extends CoffeeDecorator { public SugarDecorator(Coffee coffee) { super(coffee); } @Override public double cost() { return super.cost() + 1.0; } @Override public String description() { return super.description() + ", Sugar"; } } // 使用示例 public class DecoratorDemo { public static void main(String[] args) { Coffee coffee = new SimpleCoffee(); System.out.println(coffee.description() + " $" + coffee.cost()); coffee = new MilkDecorator(coffee); System.out.println(coffee.description() + " $" + coffee.cost()); coffee = new SugarDecorator(coffee); System.out.println(coffee.description() + " $" + coffee.cost()); } } ``` **优点**:扩展灵活,比继承更灵活 **缺点**:多层装饰会变得复杂 --- ### 10. 外观模式(Facade) **核心思想**:为子系统中的一组接口提供一个一致的界面。 **适用场景**: - 复杂的库或API - 分层架构系统 **代码示例(Java)**: ```java // 子系统A class CPU { public void start() { System.out.println("CPU started."); } public void shutdown() { System.out.println("CPU shutdown."); } } // 子系统B class Memory { public void load() { System.out.println("Memory loaded."); } public void unload() { System.out.println("Memory unloaded."); } } // 子系统C class HardDrive { public void read() { System.out.println("HardDrive reading data."); } } // 外观类 class ComputerFacade { private CPU cpu; private Memory memory; private HardDrive hardDrive; public ComputerFacade() { this.cpu = new CPU(); this.memory = new Memory(); this.hardDrive = new HardDrive(); } public void start() { System.out.println("Starting computer..."); cpu.start(); memory.load(); hardDrive.read(); System.out.println("Computer started."); } public void shutdown() { System.out.println("Shutting down computer..."); cpu.shutdown(); memory.unload(); System.out.println("Computer shutdown."); } } // 使用示例 public class FacadeDemo { public static void main(String[] args) { ComputerFacade computer = new ComputerFacade(); computer.start(); computer.shutdown(); } } ``` **优点**:减少系统依赖,提高灵活性 **缺点**:不符合开闭原则 --- ### 11. 享元模式(Flyweight) **核心思想**:运用共享技术有效地支持大量细粒度的对象。 **适用场景**: - 文本编辑器中的字符 - 五子棋游戏中的棋子 **代码示例(Java)**: ```java import java.util.HashMap; import java.util.Map; // 享元接口 interface Shape { void draw(int x, int y); } // 具体享元 class Circle implements Shape { private String color; private int radius; public Circle(String color) { this.color = color; this.radius = 10; } @Override public void draw(int x, int y) { System.out.println("Drawing Circle [Color: " + color + ", Radius: " + radius + ", x: " + x + ", y: " + y + "]"); } } // 享元工厂 class ShapeFactory { private static final Map circleMap = new HashMap<>(); public static Shape getCircle(String color) { Circle circle = (Circle) circleMap.get(color); if (circle == null) { circle = new Circle(color); circleMap.put(color, circle); System.out.println("Creating circle of color: " + color); } return circle; } } // 使用示例 public class FlyweightDemo { private static final String[] colors = {"Red", "Green", "Blue", "White", "Black"}; public static void main(String[] args) { for (int i = 0; i < 20; i++) { Circle circle = (Circle) ShapeFactory.getCircle(getRandomColor()); circle.draw(getRandomX(), getRandomY()); } } private static String getRandomColor() { return colors[(int) (Math.random() * colors.length)]; } private static int getRandomX() { return (int) (Math.random() * 100); } private static int getRandomY() { return (int) (Math.random() * 100); } } ``` **优点**:减少对象数量,降低内存占用 **缺点**:需要关注内外部状态,增加复杂度 --- ### 12. 代理模式(Proxy) **核心思想**:为其他对象提供一种代理以控制对这个对象的访问。 **适用场景**: - 远程代理 - 虚拟代理 - 保护代理 **代码示例(Java - 静态代理)**: ```java // 接口 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("Loading " + filename + " from disk."); } @Override public void display() { System.out.println("Displaying " + filename); } } // 代理类 class ProxyImage implements Image { private RealImage realImage; private String filename; public ProxyImage(String filename) { this.filename = filename; } @Override public void display() { if (realImage == null) { realImage = new RealImage(filename); } realImage.display(); } } // 使用示例 public class ProxyDemo { public static void main(String[] args) { Image image = new ProxyImage("test.jpg"); // 图片从磁盘加载 image.display(); // 图片不重新加载 image.display(); } } ``` **代码示例(Java - 动态代理)**: ```java import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; interface UserService { void addUser(String username); void deleteUser(String username); } class UserServiceImpl implements UserService { @Override public void addUser(String username) { System.out.println("Adding user: " + username); } @Override public void deleteUser(String username) { System.out.println("Deleting user: " + username); } } class LogInvocationHandler implements InvocationHandler { private Object target; public LogInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before method: " + method.getName()); Object result = method.invoke(target, args); System.out.println("After method: " + method.getName()); return result; } } // 使用示例 public class DynamicProxyDemo { public static void main(String[] args) { UserService userService = new UserServiceImpl(); UserService proxy = (UserService) Proxy.newProxyInstance( userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), new LogInvocationHandler(userService) ); proxy.addUser("Alice"); proxy.deleteUser("Bob"); } } ``` **优点**:职责清晰,扩展灵活 **缺点**:增加请求处理时间 --- ## 三、行为型模式 ### 13. 责任链模式(Chain of Responsibility) **核心思想**:将请求的发送者和接收者解耦,使多个对象都有机会处理这个请求。 **适用场景**: - 审批流程 - 异常处理链 **代码示例(Java)**: ```java // 处理者抽象类 abstract class Approver { protected Approver nextApprover; protected String name; public Approver(String name) { this.name = name; } public Approver setNext(Approver approver) { this.nextApprover = approver; return approver; } public abstract void approveRequest(double amount); } // 具体处理者 class Manager extends Approver { public Manager(String name) { super(name); } @Override public void approveRequest(double amount) { if (amount <= 1000) { System.out.println(name + " approved the request of $" + amount); } else if (nextApprover != null) { nextApprover.approveRequest(amount); } } } class Director extends Approver { public Director(String name) { super(name); } @Override public void approveRequest(double amount) { if (amount <= 5000) { System.out.println(name + " approved the request of $" + amount); } else if (nextApprover != null) { nextApprover.approveRequest(amount); } } } class CEO extends Approver { public CEO(String name) { super(name); } @Override public void approveRequest(double amount) { System.out.println(name + " approved the request of $" + amount); } } // 使用示例 public class ChainOfResponsibilityDemo { public static void main(String[] args) { Approver manager = new Manager("Manager"); Approver director = new Director("Director"); Approver ceo = new CEO("CEO"); manager.setNext(director).setNext(ceo); manager.approveRequest(500); manager.approveRequest(2000); manager.approveRequest(10000); } } ``` **优点**:降低耦合度,灵活分配责任 **缺点**:不能保证请求一定被处理 --- ### 14. 命令模式(Command) **核心思想**:将请求封装成对象,从而可用不同的请求对客户进行参数化。 **适用场景**: - GUI按钮操作 - 事务操作 **代码示例(Java)**: ```java // 命令接口 interface Command { void execute(); void undo(); } // 接收者 class Light { public void on() { System.out.println("Light is ON"); } public void off() { System.out.println("Light is OFF"); } } // 具体命令 class LightOnCommand implements Command { private Light light; public LightOnCommand(Light light) { this.light = light; } @Override public void execute() { light.on(); } @Override public void undo() { light.off(); } } class LightOffCommand implements Command { private Light light; public LightOffCommand(Light light) { this.light = light; } @Override public void execute() { light.off(); } @Override public void undo() { light.on(); } } // 调用者 class RemoteControl { private Command command; public void setCommand(Command command) { this.command = command; } public void pressButton() { command.execute(); } public void pressUndo() { command.undo(); } } // 使用示例 public class CommandDemo { public static void main(String[] args) { Light livingRoomLight = new Light(); Command lightOn = new LightOnCommand(livingRoomLight); Command lightOff = new LightOffCommand(livingRoomLight); RemoteControl remote = new RemoteControl(); remote.setCommand(lightOn); remote.pressButton(); remote.pressUndo(); remote.setCommand(lightOff); remote.pressButton(); remote.pressUndo(); } } ``` **优点**:降低系统耦合度,易于扩展 **缺点**:可能产生大量具体命令类 --- ### 15. 解释器模式(Interpreter) **核心思想**:给定一个语言,定义它的文法的一种表示,并定义一个解释器。 **适用场景**: - 正则表达式 - 表达式求值 **代码示例(Java)**: ```java import java.util.Map; // 表达式接口 interface Expression { boolean interpret(Map context); } // 终端表达式 class Variable implements Expression { private String name; public Variable(String name) { this.name = name; } @Override public boolean interpret(Map context) { return context.getOrDefault(name, false); } } // 非终端表达式 class And implements Expression { private Expression expr1; private Expression expr2; public And(Expression expr1, Expression expr2) { this.expr1 = expr1; this.expr2 = expr2; } @Override public boolean interpret(Map context) { return expr1.interpret(context) && expr2.interpret(context); } } class Or implements Expression { private Expression expr1; private Expression expr2; public Or(Expression expr1, Expression expr2) { this.expr1 = expr1; this.expr2 = expr2; } @Override public boolean interpret(Map context) { return expr1.interpret(context) || expr2.interpret(context); } } class Not implements Expression { private Expression expr; public Not(Expression expr) { this.expr = expr; } @Override public boolean interpret(Map context) { return !expr.interpret(context); } } // 使用示例 public class InterpreterDemo { public static void main(String[] args) { // 表达式: A AND (B OR NOT C) Expression expr = new And( new Variable("A"), new Or( new Variable("B"), new Not(new Variable("C")) ) ); Map context = new java.util.HashMap<>(); context.put("A", true); context.put("B", false); context.put("C", true); System.out.println("Result: " + expr.interpret(context)); // false context.put("C", false); System.out.println("Result: " + expr.interpret(context)); // true } } ``` **优点**:扩展性好,灵活 **缺点**:复杂文法难以维护,效率较低 --- ### 16. 迭代器模式(Iterator) **核心思想**:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需暴露该对象的内部表示。 **适用场景**: - 遍历集合对象 - 树形结构遍历 **代码示例(Java)**: ```java import java.util.ArrayList; import java.util.List; // 迭代器接口 interface Iterator { boolean hasNext(); T next(); } // 聚合接口 interface Aggregate { Iterator createIterator(); } // 具体聚合 class BookShelf implements Aggregate { private List books; public BookShelf() { this.books = new ArrayList<>(); } public void addBook(Book book) { books.add(book); } @Override public Iterator createIterator() { return new BookIterator(books); } } // 具体迭代器 class BookIterator implements Iterator { private List books; private int position; public BookIterator(List books) { this.books = books; this.position = 0; } @Override public boolean hasNext() { return position < books.size(); } @Override public Book next() { if (hasNext()) { return books.get(position++); } return null; } } // 书籍类 class Book { private String name; public Book(String name) { this.name = name; } public String getName() { return name; } } // 使用示例 public class IteratorDemo { public static void main(String[] args) { BookShelf bookShelf = new BookShelf(); bookShelf.addBook(new Book("设计模式")); bookShelf.addBook(new Book("Java编程思想")); bookShelf.addBook(new Book("Effective Java")); Iterator iterator = bookShelf.createIterator(); while (iterator.hasNext()) { Book book = iterator.next(); System.out.println(book.getName()); } } } ``` **优点**:支持多种遍历方式,简化聚合类 **缺点**:增加类的个数 --- ### 17. 中介者模式(Mediator) **核心思想**:用一个中介对象来封装一系列的对象交互。 **适用场景**: - 聊天室 - MVC框架中的Controller **代码示例(Java)**: ```java import java.util.ArrayList; import java.util.List; // 中介者接口 interface Mediator { void sendMessage(User user, String message); void addUser(User user); } // 用户类 class User { private String name; private Mediator mediator; public User(String name, Mediator mediator) { this.name = name; this.mediator = mediator; mediator.addUser(this); } public void send(String message) { System.out.println(name + " sending: " + message); mediator.sendMessage(this, message); } public void receive(String message) { System.out.println(name + " received: " + message); } public String getName() { return name; } } // 具体中介者 class ChatRoom implements Mediator { private List users = new ArrayList<>(); @Override public void sendMessage(User user, String message) { for (User u : users) { if (u != user) { u.receive(message); } } } @Override public void addUser(User user) { users.add(user); } } // 使用示例 public class MediatorDemo { public static void main(String[] args) { Mediator chatRoom = new ChatRoom(); User alice = new User("Alice", chatRoom); User bob = new User("Bob", chatRoom); User charlie = new User("Charlie", chatRoom); alice.send("Hello everyone!"); bob.send("Hi Alice!"); } } ``` **优点**:降低耦合,集中控制交互 **缺点**:中介者可能变得复杂 --- ### 18. 备忘录模式(Memento) **核心思想**:在不破坏封装性的前提下,捕获一个对象的内部状态。 **适用场景**: - 游戏存档 - 文本编辑器的撤销功能 **代码示例(Java)**: ```java import java.util.ArrayList; import java.util.List; // 备忘录类 class Memento { private String state; public Memento(String state) { this.state = state; } public String getState() { return state; } } // 发起人类 class Originator { private String state; public void setState(String state) { this.state = state; System.out.println("State set to: " + state); } public String getState() { return state; } public Memento saveStateToMemento() { return new Memento(state); } public void getStateFromMemento(Memento memento) { state = memento.getState(); } } // 管理者类 class CareTaker { private List mementoList = new ArrayList<>(); public void add(Memento state) { mementoList.add(state); } public Memento get(int index) { return mementoList.get(index); } } // 使用示例 public class MementoDemo { public static void main(String[] args) { Originator originator = new Originator(); CareTaker careTaker = new CareTaker(); originator.setState("State #1"); careTaker.add(originator.saveStateToMemento()); originator.setState("State #2"); careTaker.add(originator.saveStateToMemento()); originator.setState("State #3"); careTaker.add(originator.saveStateToMemento()); System.out.println("Current State: " + originator.getState()); originator.getStateFromMemento(careTaker.get(0)); System.out.println("First saved State: " + originator.getState()); originator.getStateFromMemento(careTaker.get(1)); System.out.println("Second saved State: " + originator.getState()); } } ``` **优点**:保持封装边界,简化发起人类 **缺点**:资源消耗大 --- ### 19. 观察者模式(Observer) **核心思想**:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知。 **适用场景**: - 事件驱动系统 - 订阅发布系统 **代码示例(Java - 自定义实现)**: ```java import java.util.ArrayList; import java.util.List; // 观察者接口 interface Observer { void update(String message); } // 被观察者接口 interface Subject { void attach(Observer observer); void detach(Observer observer); void notifyObservers(String message); } // 具体被观察者 class NewsAgency implements Subject { private List observers = new ArrayList<>(); @Override public void attach(Observer observer) { observers.add(observer); } @Override public void detach(Observer observer) { observers.remove(observer); } @Override public void notifyObservers(String message) { for (Observer observer : observers) { observer.update(message); } } } // 具体观察者 class NewsChannel implements Observer { private String name; public NewsChannel(String name) { this.name = name; } @Override public void update(String message) { System.out.println(name + " received news: " + message); } } // 使用示例 public class ObserverDemo { public static void main(String[] args) { NewsAgency agency = new NewsAgency(); NewsChannel channel1 = new NewsChannel("CNN"); NewsChannel channel2 = new NewsChannel("BBC"); agency.attach(channel1); agency.attach(channel2); agency.notifyObservers("Breaking: Java 21 released!"); } } ``` **代码示例(Java - 使用java.util.Observer)**: ```java import java.util.Observable; import java.util.Observer; // 被观察者 class NewsAgency2 extends Observable { public void setNews(String news) { setChanged(); notifyObservers(news); } } // 观察者 class NewsChannel2 implements Observer { private String name; public NewsChannel2(String name) { this.name = name; } @Override public void update(Observable o, Object arg) { System.out.println(name + " received: " + arg); } } // 使用示例 class ObserverDemo2 { public static void main(String[] args) { NewsAgency2 agency = new NewsAgency2(); NewsChannel2 channel1 = new NewsChannel2("CNN"); NewsChannel2 channel2 = new NewsChannel2("BBC"); agency.addObserver(channel1); agency.addObserver(channel2); agency.setNews("Breaking: New feature announced!"); } } ``` **优点**:抽象耦合,支持广播通信 **缺点**:如果观察者过多,通知会很耗时 --- ### 20. 状态模式(State) **核心思想**:允许一个对象在其内部状态改变时改变它的行为。 **适用场景**: - 订单状态流转 - 游戏角色状态 **代码示例(Java)**: ```java // 状态接口 interface State { void handle(); void changeState(Context context); } // 上下文类 class Context { private State state; public Context(State state) { this.state = state; } public void setState(State state) { this.state = state; } public void request() { state.handle(); state.changeState(this); } } // 具体状态 class StateA implements State { @Override public void handle() { System.out.println("Handling in State A"); } @Override public void changeState(Context context) { context.setState(new StateB()); System.out.println("State changed from A to B"); } } class StateB implements State { @Override public void handle() { System.out.println("Handling in State B"); } @Override public void changeState(Context context) { context.setState(new StateA()); System.out.println("State changed from B to A"); } } // 使用示例 public class StateDemo { public static void main(String[] args) { Context context = new Context(new StateA()); context.request(); context.request(); context.request(); } } ``` **优点**:结构清晰,状态转换明确 **缺点**:状态类会增多 --- ### 21. 策略模式(Strategy) **核心思想**:定义一系列算法,把它们一个个封装起来,并且使它们可相互替换。 **适用场景**: - 排序算法 - 支付方式选择 **代码示例(Java)**: ```java // 策略接口 interface PaymentStrategy { void pay(int amount); } // 具体策略 class CreditCardPayment implements PaymentStrategy { private String name; private String cardNumber; public CreditCardPayment(String name, String cardNumber) { this.name = name; this.cardNumber = cardNumber; } @Override public void pay(int amount) { System.out.println(amount + " paid with Credit Card (" + name + ")"); } } class PayPalPayment implements PaymentStrategy { private String email; public PayPalPayment(String email) { this.email = email; } @Override public void pay(int amount) { System.out.println(amount + " paid with PayPal (" + email + ")"); } } class WeChatPayment implements PaymentStrategy { private String account; public WeChatPayment(String account) { this.account = account; } @Override public void pay(int amount) { System.out.println(amount + " paid with WeChat Pay (" + account + ")"); } } // 上下文类 class ShoppingCart { private PaymentStrategy paymentStrategy; public void setPaymentStrategy(PaymentStrategy strategy) { this.paymentStrategy = strategy; } public void checkout(int amount) { paymentStrategy.pay(amount); } } // 使用示例 public class StrategyDemo { public static void main(String[] args) { ShoppingCart cart = new ShoppingCart(); cart.setPaymentStrategy(new CreditCardPayment("John Doe", "1234-5678-9012-3456")); cart.checkout(100); cart.setPaymentStrategy(new PayPalPayment("john@example.com")); cart.checkout(200); cart.setPaymentStrategy(new WeChatPayment("john123")); cart.checkout(300); } } ``` **优点**:算法可自由切换,避免多重条件 **缺点**:策略类会增多 --- ### 22. 模板方法模式(Template Method) **核心思想**:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。 **适用场景**: - Spring JdbcTemplate - Servlet的生命周期 **代码示例(Java)**: ```java // 抽象模板类 abstract class DataProcessor { // 模板方法 - final 防止子类修改 public final void process() { readData(); if (validateData()) { transformData(); saveData(); } else { System.out.println("Data validation failed!"); } } // 基本方法 - 由子类实现 protected abstract void readData(); protected abstract boolean validateData(); protected abstract void transformData(); protected abstract void saveData(); // 钩子方法 - 子类可以选择性覆盖 protected void log() { System.out.println("Default logging..."); } } // 具体模板类 class CSVDataProcessor extends DataProcessor { @Override protected void readData() { System.out.println("Reading data from CSV file"); } @Override protected boolean validateData() { System.out.println("Validating CSV data"); return true; } @Override protected void transformData() { System.out.println("Transforming CSV data"); } @Override protected void saveData() { System.out.println("Saving data to database"); } @Override protected void log() { System.out.println("CSV Processor logging..."); } } class XMLDataProcessor extends DataProcessor { @Override protected void readData() { System.out.println("Reading data from XML file"); } @Override protected boolean validateData() { System.out.println("Validating XML data"); return false; } @Override protected void transformData() { System.out.println("Transforming XML data"); } @Override protected void saveData() { System.out.println("Saving data to JSON"); } } // 使用示例 public class TemplateMethodDemo { public static void main(String[] args) { DataProcessor csvProcessor = new CSVDataProcessor(); System.out.println("=== Processing CSV ==="); csvProcessor.process(); System.out.println("\n=== Processing XML ==="); DataProcessor xmlProcessor = new XMLDataProcessor(); xmlProcessor.process(); } } ``` **优点**:封装不变部分,扩展可变部分 **缺点**:每个不同的实现都需要一个子类 --- ### 23. 访问者模式(Visitor) **核心思想**:表示一个作用于某对象结构中的各元素的操作。 **适用场景**: - 编译器(语法树) - 文档对象模型(DOM) **代码示例(Java)**: ```java import java.util.ArrayList; import java.util.List; // 访问者接口 interface Visitor { void visit(Book book); void visit(Fruit fruit); } // 元素接口 interface Element { void accept(Visitor visitor); } // 具体元素 - 书 class Book implements Element { private String isbn; private double price; public Book(String isbn, double price) { this.isbn = isbn; this.price = price; } public String getIsbn() { return isbn; } public double getPrice() { return price; } @Override public void accept(Visitor visitor) { visitor.visit(this); } } // 具体元素 - 水果 class Fruit implements Element { private String name; private double pricePerKg; private double weight; public Fruit(String name, double pricePerKg, double weight) { this.name = name; this.pricePerKg = pricePerKg; this.weight = weight; } public String getName() { return name; } public double getPricePerKg() { return pricePerKg; } public double getWeight() { return weight; } @Override public void accept(Visitor visitor) { visitor.visit(this); } } // 具体访问者 - 购物车 class ShoppingCartVisitor implements Visitor { private double totalCost = 0; @Override public void visit(Book book) { double cost = book.getPrice(); totalCost += cost; System.out.println("Book ISBN: " + book.getIsbn() + ", Cost: $" + cost); } @Override public void visit(Fruit fruit) { double cost = fruit.getPricePerKg() * fruit.getWeight(); totalCost += cost; System.out.println("Fruit: " + fruit.getName() + ", Cost: $" + cost); } public double getTotalCost() { return totalCost; } } // 具体访问者 - 库存检查 class InventoryVisitor implements Visitor { @Override public void visit(Book book) { System.out.println("Checking inventory for Book: " + book.getIsbn()); } @Override public void visit(Fruit fruit) { System.out.println("Checking inventory for Fruit: " + fruit.getName()); } } // 对象结构 class ShoppingCart { private List items = new ArrayList<>(); public void addItem(Element item) { items.add(item); } public void accept(Visitor visitor) { for (Element item : items) { item.accept(visitor); } } } // 使用示例 public class VisitorDemo { public static void main(String[] args) { ShoppingCart cart = new ShoppingCart(); cart.addItem(new Book("1234-5678", 29.99)); cart.addItem(new Book("9876-5432", 39.99)); cart.addItem(new Fruit("Apple", 1.99, 2.5)); cart.addItem(new Fruit("Orange", 2.49, 1.5)); System.out.println("=== Shopping Cart Cost ==="); ShoppingCartVisitor costVisitor = new ShoppingCartVisitor(); cart.accept(costVisitor); System.out.println("Total Cost: $" + costVisitor.getTotalCost()); System.out.println("\n=== Inventory Check ==="); InventoryVisitor inventoryVisitor = new InventoryVisitor(); cart.accept(inventoryVisitor); } } ``` **优点**:符合单一职责原则,扩展性好 **缺点**:增加新的元素类困难 --- ## 总结 ### 设计模式的选择建议 | 场景 | 推荐模式 | |------|----------| | 对象创建复杂 | 工厂方法、建造者 | | 需要共享对象 | 享元、单例 | | 接口不兼容 | 适配器 | | 动态添加功能 | 装饰器 | | 状态变化频繁 | 状态模式 | | 算法需要切换 | 策略模式 | | 事件驱动 | 观察者 | ### 学习建议 1. **从简单入手**:先掌握单例、工厂方法、观察者等常用模式 2. **结合实践**:在实际项目中识别和运用设计模式 3. **理解本质**:不要死记代码,要理解解决的问题 4. **适度使用**:避免过度设计,符合实际需求即可 ### Java语言特性与设计模式 Java语言本身已经内置了许多设计模式的应用: | Java特性 | 对应设计模式 | |---------|-------------| | `java.util.Collections` | 工厂方法 | | `java.lang.Runtime` | 单例 | | `java.io.InputStream` | 装饰器 | | `java.util.Observer` | 观察者 | | `java.lang.reflect.Proxy` | 代理 | | `javax.swing.BorderFactory` | 抽象工厂 | | `java.util.Iterator` | 迭代器 | --- **记住**:设计模式是工具,不是目的。最好的设计是能够解决问题的设计,而不是使用了最多模式的设计。 > 如果你喜欢这篇文章,欢迎点赞、收藏、分享!有问题欢迎在评论区讨论。
评论 0

发表评论 取消回复

Shift+Enter 换行  ·  Enter 发送
还没有评论,来发表第一条吧