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` | 迭代器 |
---
**记住**:设计模式是工具,不是目的。最好的设计是能够解决问题的设计,而不是使用了最多模式的设计。
> 如果你喜欢这篇文章,欢迎点赞、收藏、分享!有问题欢迎在评论区讨论。