软件设计模式详解

软件设计模式详解

我将按照创建型、结构型和行为型三大类详细讲解23个设计模式,每个模式都包含使用场景、解决问题、优点、缺点以及Java代码示例。

一、创建型模式(5个)

1. 单例模式(Singleton)

使用场景

  • 需要控制资源访问,如数据库连接池
  • 配置管理器
  • 日志记录器
  • 线程池

解决问题

  • 确保一个类只有一个实例
  • 提供全局访问点

优点

  • 减少内存开销
  • 避免资源多重占用
  • 全局访问点便于管理

缺点

  • 违反单一职责原则
  • 难以测试
  • 可能隐藏不良设计
java 复制代码
// 双重检查锁实现的单例模式
public class Singleton {
    private volatile static Singleton instance;
    
    private Singleton() {
        // 私有构造器
    }
    
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
    
    // 业务方法
    public void showMessage() {
        System.out.println("Hello Singleton Pattern!");
    }
}

// 使用示例
public class SingletonDemo {
    public static void main(String[] args) {
        Singleton singleton = Singleton.getInstance();
        singleton.showMessage();
    }
}

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

使用场景

  • 创建复杂对象
  • 需要根据条件创建不同对象
  • 数据库访问层
  • 日志记录器

解决问题

  • 对象创建与使用的解耦
  • 支持扩展新产品

优点

  • 符合开闭原则
  • 客户端代码简洁
  • 易于扩展

缺点

  • 增加类的数量
  • 增加系统复杂度
java 复制代码
// 产品接口
interface Product {
    void use();
}

// 具体产品A
class ConcreteProductA implements Product {
    @Override
    public void use() {
        System.out.println("Using Product A");
    }
}

// 具体产品B
class ConcreteProductB implements Product {
    @Override
    public void use() {
        System.out.println("Using Product B");
    }
}

// 工厂接口
interface Factory {
    Product createProduct();
}

// 具体工厂A
class ConcreteFactoryA implements Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }
}

// 具体工厂B
class ConcreteFactoryB implements Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProductB();
    }
}

// 使用示例
public class FactoryMethodDemo {
    public static void main(String[] args) {
        Factory factory = new ConcreteFactoryA();
        Product product = factory.createProduct();
        product.use();
        
        factory = new ConcreteFactoryB();
        product = factory.createProduct();
        product.use();
    }
}

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

使用场景

  • 创建相关产品族
  • 跨平台UI组件
  • 数据库迁移

解决问题

  • 创建一系列相关或依赖的对象
  • 确保产品兼容性

优点

  • 产品族一致性
  • 便于交换产品系列
  • 符合开闭原则

缺点

  • 增加系统复杂度
  • 扩展新产品困难
java 复制代码
// 抽象产品A
interface Button {
    void paint();
}

// 具体产品A1
class WindowsButton implements Button {
    @Override
    public void paint() {
        System.out.println("Rendering Windows style button");
    }
}

// 具体产品A2
class MacButton implements Button {
    @Override
    public void paint() {
        System.out.println("Rendering Mac style button");
    }
}

// 抽象产品B
interface Checkbox {
    void paint();
}

// 具体产品B1
class WindowsCheckbox implements Checkbox {
    @Override
    public void paint() {
        System.out.println("Rendering Windows style checkbox");
    }
}

// 具体产品B2
class MacCheckbox implements Checkbox {
    @Override
    public void paint() {
        System.out.println("Rendering Mac style checkbox");
    }
}

// 抽象工厂
interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

// 具体工厂1
class WindowsFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }
    
    @Override
    public Checkbox createCheckbox() {
        return new WindowsCheckbox();
    }
}

// 具体工厂2
class MacFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MacButton();
    }
    
    @Override
    public Checkbox createCheckbox() {
        return new MacCheckbox();
    }
}

// 客户端代码
public class AbstractFactoryDemo {
    private Button button;
    private Checkbox checkbox;
    
    public AbstractFactoryDemo(GUIFactory factory) {
        button = factory.createButton();
        checkbox = factory.createCheckbox();
    }
    
    public void paint() {
        button.paint();
        checkbox.paint();
    }
    
    public static void main(String[] args) {
        // 创建Windows风格界面
        GUIFactory windowsFactory = new WindowsFactory();
        AbstractFactoryDemo windowsApp = new AbstractFactoryDemo(windowsFactory);
        windowsApp.paint();
        
        // 创建Mac风格界面
        GUIFactory macFactory = new MacFactory();
        AbstractFactoryDemo macApp = new AbstractFactoryDemo(macFactory);
        macApp.paint();
    }
}

4. 建造者模式(Builder)

使用场景

  • 创建复杂对象
  • 需要多种表示的对象
  • 参数较多且有默认值

解决问题

  • 分离复杂对象的构建和表示
  • 简化客户端创建过程

优点

  • 构建过程可控
  • 易于扩展
  • 分离构造代码

缺点

  • 增加系统复杂度
  • 产品必须有共同点
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 setCPU(String CPU) {
            this.CPU = CPU;
            return this;
        }
        
        public Builder setRAM(String RAM) {
            this.RAM = RAM;
            return this;
        }
        
        public Builder setStorage(String storage) {
            this.storage = storage;
            return this;
        }
        
        public Builder setGPU(String GPU) {
            this.GPU = GPU;
            return this;
        }
        
        public Computer build() {
            return new Computer(this);
        }
    }
}

// 使用示例
public class BuilderDemo {
    public static void main(String[] args) {
        // 创建高性能电脑
        Computer gamingPC = new Computer.Builder()
            .setCPU("Intel i9")
            .setRAM("32GB")
            .setStorage("1TB SSD")
            .setGPU("RTX 3080")
            .build();
        
        System.out.println("Gaming PC: " + gamingPC);
        
        // 创建办公电脑
        Computer officePC = new Computer.Builder()
            .setCPU("Intel i5")
            .setRAM("16GB")
            .setStorage("512GB SSD")
            .build();  // 没有设置GPU
            
        System.out.println("Office PC: " + officePC);
    }
}

5. 原型模式(Prototype)

使用场景

  • 对象创建成本较高
  • 需要大量相似对象
  • 需要保存对象状态

解决问题

  • 减少对象创建开销
  • 简化对象创建过程

优点

  • 提高性能
  • 简化创建过程
  • 动态获取新对象

缺点

  • 深拷贝实现复杂
  • 需要为每个类配备克隆方法
java 复制代码
import java.util.ArrayList;
import java.util.List;

// 原型接口
interface Prototype extends Cloneable {
    Prototype clone();
}

// 具体原型类
class ConcretePrototype implements Prototype {
    private String name;
    private List<String> features;
    
    public ConcretePrototype(String name) {
        this.name = name;
        this.features = new ArrayList<>();
    }
    
    public void addFeature(String feature) {
        features.add(feature);
    }
    
    @Override
    public Prototype clone() {
        ConcretePrototype clone = new ConcretePrototype(this.name);
        // 深拷贝列表
        clone.features = new ArrayList<>(this.features);
        return clone;
    }
    
    @Override
    public String toString() {
        return "ConcretePrototype{name='" + name + "', features=" + features + "}";
    }
}

// 原型注册表
class PrototypeRegistry {
    private static java.util.Map<String, Prototype> prototypes = new java.util.HashMap<>();
    
    static {
        ConcretePrototype defaultPrototype = new ConcretePrototype("Default");
        defaultPrototype.addFeature("Basic Feature");
        prototypes.put("default", defaultPrototype);
    }
    
    public static void addPrototype(String key, Prototype prototype) {
        prototypes.put(key, prototype);
    }
    
    public static Prototype getPrototype(String key) {
        Prototype prototype = prototypes.get(key);
        return prototype != null ? prototype.clone() : null;
    }
}

// 使用示例
public class PrototypeDemo {
    public static void main(String[] args) {
        // 从注册表获取并克隆原型
        Prototype prototype1 = PrototypeRegistry.getPrototype("default");
        System.out.println("Prototype 1: " + prototype1);
        
        // 创建新原型并注册
        ConcretePrototype customPrototype = new ConcretePrototype("Custom");
        customPrototype.addFeature("Advanced Feature 1");
        customPrototype.addFeature("Advanced Feature 2");
        PrototypeRegistry.addPrototype("custom", customPrototype);
        
        // 克隆自定义原型
        Prototype prototype2 = PrototypeRegistry.getPrototype("custom");
        System.out.println("Prototype 2: " + prototype2);
        
        // 验证深拷贝
        ((ConcretePrototype) prototype2).addFeature("New Feature");
        System.out.println("Original: " + customPrototype);
        System.out.println("Cloned: " + prototype2);
    }
}

二、结构型模式(7个)

6. 适配器模式(Adapter)

使用场景

  • 系统需要复用现有类
  • 接口不兼容的类需要一起工作
  • 旧系统升级

解决问题

  • 接口不兼容问题
  • 类的复用

优点

  • 提高类的复用性
  • 增加类的透明度
  • 灵活性好

缺点

  • 过多使用会使系统混乱
  • 增加系统复杂度
java 复制代码
// 目标接口
interface MediaPlayer {
    void play(String audioType, String fileName);
}

// 需要适配的接口
interface AdvancedMediaPlayer {
    void playVlc(String fileName);
    void playMp4(String fileName);
}

// 具体实现类
class VlcPlayer implements AdvancedMediaPlayer {
    @Override
    public void playVlc(String fileName) {
        System.out.println("Playing vlc file: " + fileName);
    }
    
    @Override
    public void playMp4(String fileName) {
        // 不做任何事
    }
}

class Mp4Player implements AdvancedMediaPlayer {
    @Override
    public void playVlc(String fileName) {
        // 不做任何事
    }
    
    @Override
    public void playMp4(String fileName) {
        System.out.println("Playing mp4 file: " + fileName);
    }
}

// 适配器类
class MediaAdapter implements MediaPlayer {
    private AdvancedMediaPlayer advancedMusicPlayer;
    
    public MediaAdapter(String audioType) {
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMusicPlayer = new VlcPlayer();
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMusicPlayer = new Mp4Player();
        }
    }
    
    @Override
    public void play(String audioType, String fileName) {
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMusicPlayer.playVlc(fileName);
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMusicPlayer.playMp4(fileName);
        }
    }
}

// 客户端类
class AudioPlayer implements MediaPlayer {
    private MediaAdapter mediaAdapter;
    
    @Override
    public void play(String audioType, String fileName) {
        // 内置支持mp3格式
        if (audioType.equalsIgnoreCase("mp3")) {
            System.out.println("Playing mp3 file: " + fileName);
        } 
        // 使用适配器支持其他格式
        else if (audioType.equalsIgnoreCase("vlc") || 
                 audioType.equalsIgnoreCase("mp4")) {
            mediaAdapter = new MediaAdapter(audioType);
            mediaAdapter.play(audioType, fileName);
        } else {
            System.out.println("Invalid media type: " + audioType);
        }
    }
}

// 使用示例
public class AdapterDemo {
    public static void main(String[] args) {
        AudioPlayer audioPlayer = new AudioPlayer();
        
        audioPlayer.play("mp3", "song.mp3");
        audioPlayer.play("mp4", "video.mp4");
        audioPlayer.play("vlc", "movie.vlc");
        audioPlayer.play("avi", "movie.avi");
    }
}

7. 桥接模式(Bridge)

使用场景

  • 抽象和实现需要独立变化
  • 需要避免永久绑定
  • 多个维度变化

解决问题

  • 继承导致的类爆炸问题
  • 抽象和实现分离

优点

  • 分离抽象和实现
  • 提高系统可扩展性
  • 实现细节对客户透明

缺点

  • 增加系统复杂度
  • 需要正确识别抽象和实现
java 复制代码
// 实现化角色
interface Color {
    String applyColor();
}

// 具体实现化角色
class Red implements Color {
    @Override
    public String applyColor() {
        return "Red";
    }
}

class Blue implements Color {
    @Override
    public String applyColor() {
        return "Blue";
    }
}

// 抽象化角色
abstract class Shape {
    protected Color color;
    
    public Shape(Color color) {
        this.color = color;
    }
    
    abstract String draw();
}

// 扩展抽象化角色
class Circle extends Shape {
    public Circle(Color color) {
        super(color);
    }
    
    @Override
    String draw() {
        return "Circle drawn with color: " + color.applyColor();
    }
}

class Square extends Shape {
    public Square(Color color) {
        super(color);
    }
    
    @Override
    String draw() {
        return "Square drawn with color: " + color.applyColor();
    }
}

// 使用示例
public class BridgeDemo {
    public static void main(String[] args) {
        // 红色圆形
        Shape redCircle = new Circle(new Red());
        System.out.println(redCircle.draw());
        
        // 蓝色方形
        Shape blueSquare = new Square(new Blue());
        System.out.println(blueSquare.draw());
        
        // 蓝色圆形
        Shape blueCircle = new Circle(new Blue());
        System.out.println(blueCircle.draw());
    }
}

8. 组合模式(Composite)

使用场景

  • 表示对象的部分-整体层次结构
  • 希望客户端忽略组合与单个对象的差异
  • 树形菜单
  • 文件系统

解决问题

  • 树形结构表示
  • 统一处理简单和复杂元素

优点

  • 简化客户端代码
  • 容易添加新组件
  • 符合开闭原则

缺点

  • 设计较复杂
  • 需要限制组件类型
java 复制代码
import java.util.ArrayList;
import java.util.List;

// 组件接口
interface FileSystemComponent {
    void showDetails();
    void add(FileSystemComponent component);
    void remove(FileSystemComponent component);
}

// 叶子节点
class File implements FileSystemComponent {
    private String name;
    private int size;
    
    public File(String name, int size) {
        this.name = name;
        this.size = size;
    }
    
    @Override
    public void showDetails() {
        System.out.println("File: " + name + ", Size: " + size + "KB");
    }
    
    @Override
    public void add(FileSystemComponent component) {
        throw new UnsupportedOperationException("Cannot add to a file");
    }
    
    @Override
    public void remove(FileSystemComponent component) {
        throw new UnsupportedOperationException("Cannot remove from a file");
    }
}

// 组合节点
class Directory implements FileSystemComponent {
    private String name;
    private List<FileSystemComponent> components;
    
    public Directory(String name) {
        this.name = name;
        this.components = new ArrayList<>();
    }
    
    @Override
    public void showDetails() {
        System.out.println("\nDirectory: " + name);
        System.out.println("Contents:");
        for (FileSystemComponent component : components) {
            component.showDetails();
        }
    }
    
    @Override
    public void add(FileSystemComponent component) {
        components.add(component);
    }
    
    @Override
    public void remove(FileSystemComponent component) {
        components.remove(component);
    }
}

// 使用示例
public class CompositeDemo {
    public static void main(String[] args) {
        // 创建文件
        FileSystemComponent file1 = new File("Document.txt", 100);
        FileSystemComponent file2 = new File("Image.jpg", 2000);
        FileSystemComponent file3 = new File("Video.mp4", 50000);
        
        // 创建目录
        Directory documents = new Directory("Documents");
        Directory media = new Directory("Media");
        Directory root = new Directory("Root");
        
        // 构建树形结构
        documents.add(file1);
        
        media.add(file2);
        media.add(file3);
        
        root.add(documents);
        root.add(media);
        
        // 显示结构
        root.showDetails();
        
        // 也可以单独显示
        System.out.println("\n--- Showing media directory ---");
        media.showDetails();
    }
}

9. 装饰器模式(Decorator)

使用场景

  • 动态添加职责
  • 需要扩展功能但不想使用继承
  • I/O流处理

解决问题

  • 扩展对象功能
  • 避免子类膨胀

优点

  • 比继承更灵活
  • 可以动态添加功能
  • 符合开闭原则

缺点

  • 增加系统复杂度
  • 多层装饰难以调试
java 复制代码
// 组件接口
interface Coffee {
    double getCost();
    String getDescription();
}

// 具体组件
class SimpleCoffee implements Coffee {
    @Override
    public double getCost() {
        return 10.0;
    }
    
    @Override
    public String getDescription() {
        return "Simple coffee";
    }
}

// 装饰器基类
abstract class CoffeeDecorator implements Coffee {
    protected Coffee decoratedCoffee;
    
    public CoffeeDecorator(Coffee coffee) {
        this.decoratedCoffee = coffee;
    }
    
    @Override
    public double getCost() {
        return decoratedCoffee.getCost();
    }
    
    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription();
    }
}

// 具体装饰器
class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }
    
    @Override
    public double getCost() {
        return super.getCost() + 2.0;
    }
    
    @Override
    public String getDescription() {
        return super.getDescription() + ", with milk";
    }
}

class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee coffee) {
        super(coffee);
    }
    
    @Override
    public double getCost() {
        return super.getCost() + 1.0;
    }
    
    @Override
    public String getDescription() {
        return super.getDescription() + ", with sugar";
    }
}

class WhippedCreamDecorator extends CoffeeDecorator {
    public WhippedCreamDecorator(Coffee coffee) {
        super(coffee);
    }
    
    @Override
    public double getCost() {
        return super.getCost() + 3.0;
    }
    
    @Override
    public String getDescription() {
        return super.getDescription() + ", with whipped cream";
    }
}

// 使用示例
public class DecoratorDemo {
    public static void main(String[] args) {
        // 简单咖啡
        Coffee coffee = new SimpleCoffee();
        System.out.println("Cost: " + coffee.getCost() + 
                         "; Description: " + coffee.getDescription());
        
        // 加牛奶
        coffee = new MilkDecorator(coffee);
        System.out.println("Cost: " + coffee.getCost() + 
                         "; Description: " + coffee.getDescription());
        
        // 加糖
        coffee = new SugarDecorator(coffee);
        System.out.println("Cost: " + coffee.getCost() + 
                         "; Description: " + coffee.getDescription());
        
        // 加奶油
        coffee = new WhippedCreamDecorator(coffee);
        System.out.println("Cost: " + coffee.getCost() + 
                         "; Description: " + coffee.getDescription());
    }
}

10. 外观模式(Facade)

使用场景

  • 复杂子系统需要简单接口
  • 分层架构
  • 减少系统依赖

解决问题

  • 简化复杂系统接口
  • 降低系统耦合度

优点

  • 简化客户端使用
  • 减少系统依赖
  • 提高安全性

缺点

  • 不符合开闭原则
  • 可能成为"上帝对象"
java 复制代码
// 子系统1
class CPU {
    public void freeze() {
        System.out.println("CPU freeze");
    }
    
    public void jump(long position) {
        System.out.println("CPU jump to position: " + position);
    }
    
    public void execute() {
        System.out.println("CPU execute");
    }
}

// 子系统2
class Memory {
    public void load(long position, byte[] data) {
        System.out.println("Memory load at position: " + position);
    }
}

// 子系统3
class HardDrive {
    public byte[] read(long lba, int size) {
        System.out.println("HardDrive read at LBA: " + lba + ", size: " + size);
        return new byte[size];
    }
}

// 外观类
class ComputerFacade {
    private CPU processor;
    private Memory ram;
    private HardDrive hd;
    
    public ComputerFacade() {
        this.processor = new CPU();
        this.ram = new Memory();
        this.hd = new HardDrive();
    }
    
    public void start() {
        System.out.println("Computer starting...");
        processor.freeze();
        ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE));
        processor.jump(BOOT_ADDRESS);
        processor.execute();
        System.out.println("Computer started successfully!");
    }
    
    private static final long BOOT_ADDRESS = 0x0000;
    private static final long BOOT_SECTOR = 0x0007;
    private static final int SECTOR_SIZE = 1024;
}

// 使用示例
public class FacadeDemo {
    public static void main(String[] args) {
        ComputerFacade computer = new ComputerFacade();
        computer.start();
        
        // 客户端不需要了解子系统细节
        // 只需要调用外观类的简单接口
    }
}

11. 享元模式(Flyweight)

使用场景

  • 大量相似对象
  • 对象状态可以外部化
  • 内存消耗大
  • 游戏中的子弹、粒子

解决问题

  • 减少内存使用
  • 共享相似对象

优点

  • 减少内存消耗
  • 提高性能

缺点

  • 增加系统复杂度
  • 外部状态可能影响行为
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; // 默认半径
    }
    
    public void setRadius(int radius) {
        this.radius = radius;
    }
    
    @Override
    public void draw(int x, int y) {
        System.out.println("Drawing Circle [Color: " + color + 
                         ", Radius: " + radius + 
                         ", Position: (" + x + ", " + y + ")]");
    }
}

// 享元工厂
class ShapeFactory {
    private static final Map<String, Shape> 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 static int getCircleCount() {
        return circleMap.size();
    }
}

// 使用示例
public class FlyweightDemo {
    private static final String[] colors = {"Red", "Green", "Blue", "Yellow", "Black"};
    
    public static void main(String[] args) {
        System.out.println("Drawing 20 circles with 5 colors:");
        
        for (int i = 0; i < 20; i++) {
            Circle circle = (Circle) ShapeFactory.getCircle(getRandomColor());
            circle.setRadius(getRandomRadius());
            circle.draw(getRandomX(), getRandomY());
        }
        
        System.out.println("\nTotal circles created: " + ShapeFactory.getCircleCount());
    }
    
    private static String getRandomColor() {
        return colors[(int)(Math.random() * colors.length)];
    }
    
    private static int getRandomRadius() {
        return (int)(Math.random() * 20) + 5;
    }
    
    private static int getRandomX() {
        return (int)(Math.random() * 100);
    }
    
    private static int getRandomY() {
        return (int)(Math.random() * 100);
    }
}

12. 代理模式(Proxy)

使用场景

  • 远程代理
  • 虚拟代理
  • 安全代理
  • 智能引用

解决问题

  • 控制对象访问
  • 延迟加载
  • 访问权限控制

优点

  • 职责清晰
  • 高扩展性
  • 智能化

缺点

  • 增加系统复杂度
  • 可能降低性能
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 image: " + fileName);
    }
    
    @Override
    public void display() {
        System.out.println("Displaying image: " + 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();
    }
}

// 虚拟代理示例:延迟加载
class VirtualProxyDemo {
    public static void main(String[] args) {
        System.out.println("Virtual Proxy Example:");
        Image image = new ProxyImage("test_image.jpg");
        
        // 图像不会立即加载
        System.out.println("Image object created, but not loaded yet.");
        
        // 第一次显示,图像会加载
        System.out.println("First display:");
        image.display();
        
        // 第二次显示,图像已加载,直接显示
        System.out.println("\nSecond display:");
        image.display();
    }
}

// 保护代理示例
interface Internet {
    void connectTo(String serverHost) throws Exception;
}

class RealInternet implements Internet {
    @Override
    public void connectTo(String serverHost) {
        System.out.println("Connecting to: " + serverHost);
    }
}

class ProxyInternet implements Internet {
    private Internet internet = new RealInternet();
    private static java.util.List<String> bannedSites;
    
    static {
        bannedSites = new java.util.ArrayList<>();
        bannedSites.add("banned.com");
        bannedSites.add("blocked.com");
    }
    
    @Override
    public void connectTo(String serverHost) throws Exception {
        if (bannedSites.contains(serverHost.toLowerCase())) {
            throw new Exception("Access Denied to: " + serverHost);
        }
        internet.connectTo(serverHost);
    }
}

// 使用示例
public class ProxyDemo {
    public static void main(String[] args) {
        System.out.println("\nProtection Proxy Example:");
        Internet internet = new ProxyInternet();
        
        try {
            internet.connectTo("google.com");
            internet.connectTo("banned.com");
        } catch (Exception e) {
            System.out.println("Exception: " + e.getMessage());
        }
    }
}

三、行为型模式(11个)

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

使用场景

  • 多个对象处理同一请求
  • 审批流程
  • 异常处理
  • 事件处理

解决问题

  • 请求发送者和接收者解耦
  • 动态指定处理者

优点

  • 降低耦合度
  • 增加灵活性
  • 简化对象连接

缺点

  • 请求可能未处理
  • 性能受影响
java 复制代码
// 处理者接口
abstract class Logger {
    public static int INFO = 1;
    public static int DEBUG = 2;
    public static int ERROR = 3;
    
    protected int level;
    protected Logger nextLogger;
    
    public void setNextLogger(Logger nextLogger) {
        this.nextLogger = nextLogger;
    }
    
    public void logMessage(int level, String message) {
        if (this.level <= level) {
            write(message);
        }
        if (nextLogger != null) {
            nextLogger.logMessage(level, message);
        }
    }
    
    abstract protected void write(String message);
}

// 具体处理者
class ConsoleLogger extends Logger {
    public ConsoleLogger(int level) {
        this.level = level;
    }
    
    @Override
    protected void write(String message) {
        System.out.println("Console Logger: " + message);
    }
}

class FileLogger extends Logger {
    public FileLogger(int level) {
        this.level = level;
    }
    
    @Override
    protected void write(String message) {
        System.out.println("File Logger: " + message);
    }
}

class ErrorLogger extends Logger {
    public ErrorLogger(int level) {
        this.level = level;
    }
    
    @Override
    protected void write(String message) {
        System.out.println("Error Logger: " + message);
    }
}

// 使用示例
public class ChainOfResponsibilityDemo {
    private static Logger getChainOfLoggers() {
        Logger errorLogger = new ErrorLogger(Logger.ERROR);
        Logger fileLogger = new FileLogger(Logger.DEBUG);
        Logger consoleLogger = new ConsoleLogger(Logger.INFO);
        
        errorLogger.setNextLogger(fileLogger);
        fileLogger.setNextLogger(consoleLogger);
        
        return errorLogger;
    }
    
    public static void main(String[] args) {
        Logger loggerChain = getChainOfLoggers();
        
        System.out.println("Logging INFO level:");
        loggerChain.logMessage(Logger.INFO, "This is an information.");
        
        System.out.println("\nLogging DEBUG level:");
        loggerChain.logMessage(Logger.DEBUG, "This is a debug level information.");
        
        System.out.println("\nLogging ERROR level:");
        loggerChain.logMessage(Logger.ERROR, "This is an error information.");
    }
}

14. 命令模式(Command)

使用场景

  • 需要将请求封装为对象
  • 支持撤销/重做
  • 任务队列
  • 事务处理

解决问题

  • 请求发送者和接收者解耦
  • 支持命令队列和日志

优点

  • 降低系统耦合度
  • 容易扩展新命令
  • 支持撤销/重做

缺点

  • 增加系统复杂度
  • 可能产生过多具体命令类
java 复制代码
import java.util.ArrayList;
import java.util.List;

// 命令接口
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;
    private List<Command> history = new ArrayList<>();
    
    public void setCommand(Command command) {
        this.command = command;
    }
    
    public void pressButton() {
        command.execute();
        history.add(command);
    }
    
    public void pressUndo() {
        if (!history.isEmpty()) {
            Command lastCommand = history.remove(history.size() - 1);
            lastCommand.undo();
        }
    }
}

// 宏命令
class MacroCommand implements Command {
    private List<Command> commands = new ArrayList<>();
    
    public void addCommand(Command command) {
        commands.add(command);
    }
    
    @Override
    public void execute() {
        for (Command command : commands) {
            command.execute();
        }
    }
    
    @Override
    public void undo() {
        // 逆序执行撤销
        for (int i = commands.size() - 1; i >= 0; i--) {
            commands.get(i).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();
        
        // 测试
        System.out.println("Turning light on:");
        remote.setCommand(lightOn);
        remote.pressButton();
        
        System.out.println("\nUndoing last command:");
        remote.pressUndo();
        
        System.out.println("\nTurning light off:");
        remote.setCommand(lightOff);
        remote.pressButton();
        
        // 宏命令示例
        System.out.println("\nMacro Command Example:");
        MacroCommand partyMode = new MacroCommand();
        partyMode.addCommand(lightOn);
        partyMode.addCommand(lightOff);
        partyMode.addCommand(lightOn);
        
        remote.setCommand(partyMode);
        remote.pressButton();
        
        System.out.println("\nUndoing macro command:");
        remote.pressUndo();
    }
}

15. 解释器模式(Interpreter)

使用场景

  • 特定类型问题频繁发生
  • 简单语法解释器
  • 正则表达式
  • SQL解析

解决问题

  • 特定领域语言
  • 文法表示

优点

  • 容易改变和扩展文法
  • 实现文法容易

缺点

  • 执行效率低
  • 复杂文法难以维护
java 复制代码
import java.util.Map;
import java.util.HashMap;

// 表达式接口
interface Expression {
    boolean interpret(Map<String, Boolean> context);
}

// 终结符表达式
class Variable implements Expression {
    private String name;
    
    public Variable(String name) {
        this.name = name;
    }
    
    @Override
    public boolean interpret(Map<String, Boolean> context) {
        return context.getOrDefault(name, false);
    }
}

// 非终结符表达式
class AndExpression implements Expression {
    private Expression expr1;
    private Expression expr2;
    
    public AndExpression(Expression expr1, Expression expr2) {
        this.expr1 = expr1;
        this.expr2 = expr2;
    }
    
    @Override
    public boolean interpret(Map<String, Boolean> context) {
        return expr1.interpret(context) && expr2.interpret(context);
    }
}

class OrExpression implements Expression {
    private Expression expr1;
    private Expression expr2;
    
    public OrExpression(Expression expr1, Expression expr2) {
        this.expr1 = expr1;
        this.expr2 = expr2;
    }
    
    @Override
    public boolean interpret(Map<String, Boolean> context) {
        return expr1.interpret(context) || expr2.interpret(context);
    }
}

class NotExpression implements Expression {
    private Expression expr;
    
    public NotExpression(Expression expr) {
        this.expr = expr;
    }
    
    @Override
    public boolean interpret(Map<String, Boolean> context) {
        return !expr.interpret(context);
    }
}

// 构建解析树
class ExpressionBuilder {
    public static Expression buildExpression(String expression) {
        // 简化实现,实际应用中需要完整的语法解析
        if (expression.contains("AND")) {
            String[] parts = expression.split(" AND ");
            return new AndExpression(new Variable(parts[0].trim()), 
                                   new Variable(parts[1].trim()));
        } else if (expression.contains("OR")) {
            String[] parts = expression.split(" OR ");
            return new OrExpression(new Variable(parts[0].trim()), 
                                  new Variable(parts[1].trim()));
        } else if (expression.startsWith("NOT ")) {
            return new NotExpression(new Variable(expression.substring(4).trim()));
        } else {
            return new Variable(expression.trim());
        }
    }
}

// 使用示例
public class InterpreterDemo {
    public static void main(String[] args) {
        // 创建上下文
        Map<String, Boolean> context = new HashMap<>();
        context.put("A", true);
        context.put("B", false);
        context.put("C", true);
        
        // 构建表达式
        Expression expr1 = ExpressionBuilder.buildExpression("A AND B");
        Expression expr2 = ExpressionBuilder.buildExpression("A OR B");
        Expression expr3 = ExpressionBuilder.buildExpression("NOT C");
        Expression expr4 = ExpressionBuilder.buildExpression("A AND B OR C");
        
        // 解释表达式
        System.out.println("A AND B = " + expr1.interpret(context));
        System.out.println("A OR B = " + expr2.interpret(context));
        System.out.println("NOT C = " + expr3.interpret(context));
        
        // 复合表达式
        Expression expr5 = new AndExpression(
            new Variable("A"),
            new OrExpression(new Variable("B"), new Variable("C"))
        );
        System.out.println("A AND (B OR C) = " + expr5.interpret(context));
    }
}

16. 迭代器模式(Iterator)

使用场景

  • 访问聚合对象内容
  • 支持多种遍历方式
  • 统一遍历接口

解决问题

  • 遍历与聚合分离
  • 支持多种遍历

优点

  • 支持多种遍历方式
  • 简化聚合类
  • 符合单一职责原则

缺点

  • 增加系统复杂度
  • 对于简单聚合可能过度设计
java 复制代码
import java.util.ArrayList;
import java.util.List;

// 迭代器接口
interface Iterator<T> {
    boolean hasNext();
    T next();
}

// 聚合接口
interface Container<T> {
    Iterator<T> getIterator();
}

// 具体聚合类
class NameRepository implements Container<String> {
    private String[] names = {"Robert", "John", "Julie", "Lora"};
    
    @Override
    public Iterator<String> getIterator() {
        return new NameIterator();
    }
    
    // 具体迭代器
    private class NameIterator implements Iterator<String> {
        private int index;
        
        @Override
        public boolean hasNext() {
            return index < names.length;
        }
        
        @Override
        public String next() {
            if (hasNext()) {
                return names[index++];
            }
            return null;
        }
    }
}

// 自定义集合类
class CustomCollection<T> implements Container<T> {
    private List<T> items = new ArrayList<>();
    
    public void add(T item) {
        items.add(item);
    }
    
    public void remove(T item) {
        items.remove(item);
    }
    
    @Override
    public Iterator<T> getIterator() {
        return new ListIterator();
    }
    
    // 正向迭代器
    private class ListIterator implements Iterator<T> {
        private int index = 0;
        
        @Override
        public boolean hasNext() {
            return index < items.size();
        }
        
        @Override
        public T next() {
            if (hasNext()) {
                return items.get(index++);
            }
            return null;
        }
    }
    
    // 反向迭代器
    public Iterator<T> getReverseIterator() {
        return new ReverseIterator();
    }
    
    private class ReverseIterator implements Iterator<T> {
        private int index = items.size() - 1;
        
        @Override
        public boolean hasNext() {
            return index >= 0;
        }
        
        @Override
        public T next() {
            if (hasNext()) {
                return items.get(index--);
            }
            return null;
        }
    }
}

// 使用示例
public class IteratorDemo {
    public static void main(String[] args) {
        System.out.println("Name Repository Iterator:");
        NameRepository nameRepository = new NameRepository();
        Iterator<String> iterator = nameRepository.getIterator();
        
        while (iterator.hasNext()) {
            String name = iterator.next();
            System.out.println("Name: " + name);
        }
        
        System.out.println("\nCustom Collection Iterator:");
        CustomCollection<String> collection = new CustomCollection<>();
        collection.add("Apple");
        collection.add("Banana");
        collection.add("Cherry");
        collection.add("Date");
        
        System.out.println("Forward iteration:");
        Iterator<String> forwardIterator = collection.getIterator();
        while (forwardIterator.hasNext()) {
            System.out.println(forwardIterator.next());
        }
        
        System.out.println("\nReverse iteration:");
        Iterator<String> reverseIterator = collection.getReverseIterator();
        while (reverseIterator.hasNext()) {
            System.out.println(reverseIterator.next());
        }
    }
}

17. 中介者模式(Mediator)

使用场景

  • 对象间交互复杂
  • 聊天室
  • 机场调度系统
  • MVC控制器

解决问题

  • 减少对象间直接通信
  • 集中控制逻辑

优点

  • 降低类间耦合
  • 简化对象协议
  • 集中控制逻辑

缺点

  • 中介者可能过于复杂
  • 可能成为性能瓶颈
java 复制代码
import java.util.ArrayList;
import java.util.List;
import java.util.Date;

// 中介者接口
interface ChatMediator {
    void sendMessage(String msg, User user);
    void addUser(User user);
}

// 具体中介者
class ChatMediatorImpl implements ChatMediator {
    private List<User> users;
    
    public ChatMediatorImpl() {
        this.users = new ArrayList<>();
    }
    
    @Override
    public void addUser(User user) {
        this.users.add(user);
    }
    
    @Override
    public void sendMessage(String msg, User user) {
        for (User u : this.users) {
            // 消息不应该发送给发送者自己
            if (u != user) {
                u.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 UserImpl extends User {
    public UserImpl(ChatMediator mediator, String name) {
        super(mediator, name);
    }
    
    @Override
    public void send(String msg) {
        System.out.println(this.name + " sending message: " + msg);
        mediator.sendMessage(msg, this);
    }
    
    @Override
    public void receive(String msg) {
        System.out.println(this.name + " received message: " + msg);
    }
}

// 管理员用户
class AdminUser extends User {
    public AdminUser(ChatMediator mediator, String name) {
        super(mediator, name);
    }
    
    @Override
    public void send(String msg) {
        System.out.println("[Admin] " + this.name + " sending message: " + msg);
        mediator.sendMessage("[Admin] " + msg, this);
    }
    
    @Override
    public void receive(String msg) {
        System.out.println("[Admin] " + this.name + " received message: " + msg);
    }
    
    public void sendToUser(String msg, User targetUser) {
        System.out.println("[Admin " + this.name + " to " + targetUser.name + "]: " + msg);
        // 在实际应用中,这里应该有直接发送给特定用户的逻辑
    }
}

// 使用示例
public class MediatorDemo {
    public static void main(String[] args) {
        ChatMediator mediator = new ChatMediatorImpl();
        
        User user1 = new UserImpl(mediator, "Alice");
        User user2 = new UserImpl(mediator, "Bob");
        User user3 = new UserImpl(mediator, "Charlie");
        User admin = new AdminUser(mediator, "Admin");
        
        mediator.addUser(user1);
        mediator.addUser(user2);
        mediator.addUser(user3);
        mediator.addUser(admin);
        
        System.out.println("Chat Room Conversation:");
        user1.send("Hi everyone!");
        user2.send("Hello Alice!");
        admin.send("Welcome to the chat room!");
        user3.send("Good to be here!");
    }
}

18. 备忘录模式(Memento)

使用场景

  • 需要保存对象状态
  • 需要撤销操作
  • 游戏存档
  • 事务回滚

解决问题

  • 状态保存和恢复
  • 封装状态信息

优点

  • 状态恢复机制
  • 信息封装
  • 简化发起者

缺点

  • 资源消耗大
  • 可能暴露实现细节
java 复制代码
import java.util.ArrayList;
import java.util.List;

// 备忘录类
class Memento {
    private final 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();
        System.out.println("State restored to: " + state);
    }
}

// 管理者类
class CareTaker {
    private List<Memento> mementoList = new ArrayList<>();
    
    public void add(Memento state) {
        mementoList.add(state);
    }
    
    public Memento get(int index) {
        return mementoList.get(index);
    }
    
    public List<Memento> getAll() {
        return new ArrayList<>(mementoList);
    }
}

// 文本编辑器示例
class TextEditor {
    private String text;
    private int cursorPosition;
    
    public void setText(String text) {
        this.text = text;
    }
    
    public void setCursorPosition(int position) {
        this.cursorPosition = position;
    }
    
    public EditorMemento save() {
        return new EditorMemento(text, cursorPosition);
    }
    
    public void restore(EditorMemento memento) {
        this.text = memento.getText();
        this.cursorPosition = memento.getCursorPosition();
        System.out.println("Text Editor restored to: \"" + text + 
                         "\" at position: " + cursorPosition);
    }
    
    public void print() {
        System.out.println("Text: \"" + text + "\", Cursor at: " + cursorPosition);
    }
    
    // 编辑器备忘录
    static class EditorMemento {
        private final String text;
        private final int cursorPosition;
        
        public EditorMemento(String text, int cursorPosition) {
            this.text = text;
            this.cursorPosition = cursorPosition;
        }
        
        public String getText() {
            return text;
        }
        
        public int getCursorPosition() {
            return cursorPosition;
        }
    }
}

// 使用示例
public class MementoDemo {
    public static void main(String[] args) {
        System.out.println("=== Basic Memento Example ===");
        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");
        System.out.println("Current State: " + originator.getState());
        
        originator.getStateFromMemento(careTaker.get(0));
        originator.getStateFromMemento(careTaker.get(1));
        
        System.out.println("\n=== Text Editor Example ===");
        TextEditor editor = new TextEditor();
        List<TextEditor.EditorMemento> savedStates = new ArrayList<>();
        
        editor.setText("Hello World");
        editor.setCursorPosition(5);
        savedStates.add(editor.save());
        editor.print();
        
        editor.setText("Goodbye World");
        editor.setCursorPosition(8);
        savedStates.add(editor.save());
        editor.print();
        
        editor.setText("Modified Text");
        editor.setCursorPosition(10);
        editor.print();
        
        System.out.println("\nRestoring to first save:");
        editor.restore(savedStates.get(0));
        
        System.out.println("Restoring to second save:");
        editor.restore(savedStates.get(1));
    }
}

19. 观察者模式(Observer)

使用场景

  • 对象状态变化通知
  • 事件驱动系统
  • MVC模式
  • 消息队列

解决问题

  • 一对多依赖关系
  • 对象状态同步

优点

  • 抽象耦合
  • 支持广播通信
  • 符合开闭原则

缺点

  • 通知顺序不确定
  • 可能引起循环引用
java 复制代码
import java.util.ArrayList;
import java.util.List;

// 观察者接口
interface Observer {
    void update(String message);
}

// 主题接口
interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

// 具体主题
class NewsAgency implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String news;
    
    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }
    
    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }
    
    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(news);
        }
    }
    
    public void setNews(String news) {
        this.news = news;
        notifyObservers();
    }
}

// 具体观察者
class NewsChannel implements Observer {
    private String name;
    private String latestNews;
    
    public NewsChannel(String name) {
        this.name = name;
    }
    
    @Override
    public void update(String news) {
        this.latestNews = news;
        display();
    }
    
    public void display() {
        System.out.println(name + " received news: " + latestNews);
    }
}

// 推拉模型示例
interface StockObserver {
    void update(double price, String symbol);
}

class StockMarket implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String stockSymbol;
    private double stockPrice;
    
    public StockMarket(String symbol, double price) {
        this.stockSymbol = symbol;
        this.stockPrice = price;
    }
    
    public void setPrice(double price) {
        this.stockPrice = price;
        notifyObservers();
    }
    
    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }
    
    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }
    
    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            // 推模型:主动发送数据
            observer.update(stockSymbol + " price changed to: $" + stockPrice);
        }
    }
    
    // 拉模型:观察者主动获取数据
    public double getStockPrice() {
        return stockPrice;
    }
    
    public String getStockSymbol() {
        return stockSymbol;
    }
}

class StockDisplay implements Observer {
    private StockMarket market;
    
    public StockDisplay(StockMarket market) {
        this.market = market;
        market.registerObserver(this);
    }
    
    @Override
    public void update(String message) {
        System.out.println("Stock Update: " + message);
        // 可以主动拉取更多数据
        System.out.println("Current " + market.getStockSymbol() + 
                         " price: $" + market.getStockPrice());
    }
}

// 使用示例
public class ObserverDemo {
    public static void main(String[] args) {
        System.out.println("=== News Agency Example ===");
        NewsAgency agency = new NewsAgency();
        
        NewsChannel channel1 = new NewsChannel("CNN");
        NewsChannel channel2 = new NewsChannel("BBC");
        NewsChannel channel3 = new NewsChannel("Fox News");
        
        agency.registerObserver(channel1);
        agency.registerObserver(channel2);
        agency.registerObserver(channel3);
        
        agency.setNews("Breaking News: Observer Pattern is awesome!");
        
        agency.removeObserver(channel2);
        System.out.println("\nAfter removing BBC:");
        agency.setNews("Update: Design Patterns are useful!");
        
        System.out.println("\n=== Stock Market Example ===");
        StockMarket appleStock = new StockMarket("AAPL", 150.0);
        StockDisplay display1 = new StockDisplay(appleStock);
        
        appleStock.setPrice(152.5);
        appleStock.setPrice(155.0);
    }
}

20. 状态模式(State)

使用场景

  • 对象行为随状态改变
  • 状态转换复杂
  • 条件语句过多
  • 工作流引擎

解决问题

  • 状态转换逻辑
  • 消除条件语句

优点

  • 状态转换显式化
  • 状态类职责单一
  • 易于扩展新状态

缺点

  • 增加系统复杂度
  • 状态类数量多
java 复制代码
// 状态接口
interface State {
    void handle(Context context);
}

// 具体状态
class StartState implements State {
    @Override
    public void handle(Context context) {
        System.out.println("Player is in start state");
        context.setState(this);
    }
    
    @Override
    public String toString() {
        return "Start State";
    }
}

class StopState implements State {
    @Override
    public void handle(Context context) {
        System.out.println("Player is in stop state");
        context.setState(this);
    }
    
    @Override
    public String toString() {
        return "Stop State";
    }
}

class PauseState implements State {
    @Override
    public void handle(Context context) {
        System.out.println("Player is in pause state");
        context.setState(this);
    }
    
    @Override
    public String toString() {
        return "Pause State";
    }
}

// 上下文
class Context {
    private State state;
    
    public Context() {
        state = null;
    }
    
    public void setState(State state) {
        this.state = state;
    }
    
    public State getState() {
        return state;
    }
}

// 交通灯示例
interface TrafficLightState {
    void change(TrafficLight light);
    void display();
}

class RedLight implements TrafficLightState {
    @Override
    public void change(TrafficLight light) {
        System.out.println("Red light for 60 seconds...");
        try {
            Thread.sleep(1000); // 模拟等待
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        light.setState(new GreenLight());
    }
    
    @Override
    public void display() {
        System.out.println("[RED LIGHT] - STOP");
    }
}

class YellowLight implements TrafficLightState {
    @Override
    public void change(TrafficLight light) {
        System.out.println("Yellow light for 5 seconds...");
        try {
            Thread.sleep(500); // 模拟等待
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        light.setState(new RedLight());
    }
    
    @Override
    public void display() {
        System.out.println("[YELLOW LIGHT] - CAUTION");
    }
}

class GreenLight implements TrafficLightState {
    @Override
    public void change(TrafficLight light) {
        System.out.println("Green light for 55 seconds...");
        try {
            Thread.sleep(1000); // 模拟等待
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        light.setState(new YellowLight());
    }
    
    @Override
    public void display() {
        System.out.println("[GREEN LIGHT] - GO");
    }
}

class TrafficLight {
    private TrafficLightState state;
    
    public TrafficLight() {
        this.state = new RedLight();
    }
    
    public void setState(TrafficLightState state) {
        this.state = state;
    }
    
    public void change() {
        state.change(this);
    }
    
    public void display() {
        state.display();
    }
    
    public void runCycle(int cycles) {
        for (int i = 0; i < cycles; i++) {
            System.out.println("\nCycle " + (i + 1) + ":");
            display();
            change();
        }
    }
}

// 使用示例
public class StateDemo {
    public static void main(String[] args) {
        System.out.println("=== Media Player State Example ===");
        Context context = new Context();
        
        StartState startState = new StartState();
        startState.handle(context);
        System.out.println("Current state: " + context.getState());
        
        StopState stopState = new StopState();
        stopState.handle(context);
        System.out.println("Current state: " + context.getState());
        
        System.out.println("\n=== Traffic Light State Example ===");
        TrafficLight trafficLight = new TrafficLight();
        trafficLight.runCycle(3);
    }
}

21. 策略模式(Strategy)

使用场景

  • 多种算法变体
  • 需要动态切换算法
  • 消除条件语句
  • 支付方式选择

解决问题

  • 算法封装和切换
  • 消除条件分支

优点

  • 算法可互换
  • 扩展性好
  • 避免多重条件

缺点

  • 策略类增多
  • 客户端需要了解策略
java 复制代码
import java.util.Arrays;
import java.util.List;

// 策略接口
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");
        System.out.println("Cardholder: " + name);
        System.out.println("Card number: " + maskCardNumber(cardNumber));
    }
    
    private String maskCardNumber(String cardNumber) {
        if (cardNumber.length() > 4) {
            return "****-****-****-" + cardNumber.substring(cardNumber.length() - 4);
        }
        return cardNumber;
    }
}

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 using PayPal");
        System.out.println("Email: " + email);
    }
}

class BitcoinPayment implements PaymentStrategy {
    private String walletAddress;
    
    public BitcoinPayment(String walletAddress) {
        this.walletAddress = walletAddress;
    }
    
    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid using Bitcoin");
        System.out.println("Wallet address: " + walletAddress);
    }
}

// 上下文
class ShoppingCart {
    private List<String> items;
    private PaymentStrategy paymentStrategy;
    
    public ShoppingCart() {
        this.items = new java.util.ArrayList<>();
    }
    
    public void addItem(String item) {
        items.add(item);
    }
    
    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }
    
    public void checkout(int amount) {
        if (paymentStrategy == null) {
            System.out.println("Please select a payment method");
            return;
        }
        System.out.println("Checking out items: " + items);
        paymentStrategy.pay(amount);
        items.clear();
    }
}

// 排序策略示例
interface SortStrategy {
    void sort(List<Integer> list);
}

class BubbleSort implements SortStrategy {
    @Override
    public void sort(List<Integer> list) {
        System.out.println("Sorting using Bubble Sort");
        // 简化实现
        list.sort(Integer::compareTo);
    }
}

class QuickSort implements SortStrategy {
    @Override
    public void sort(List<Integer> list) {
        System.out.println("Sorting using Quick Sort");
        // 简化实现
        list.sort(Integer::compareTo);
    }
}

class MergeSort implements SortStrategy {
    @Override
    public void sort(List<Integer> list) {
        System.out.println("Sorting using Merge Sort");
        // 简化实现
        list.sort(Integer::compareTo);
    }
}

class Sorter {
    private SortStrategy strategy;
    
    public void setStrategy(SortStrategy strategy) {
        this.strategy = strategy;
    }
    
    public void sortList(List<Integer> list) {
        if (strategy == null) {
            throw new IllegalStateException("Sort strategy not set");
        }
        strategy.sort(list);
        System.out.println("Sorted list: " + list);
    }
}

// 使用示例
public class StrategyDemo {
    public static void main(String[] args) {
        System.out.println("=== Payment Strategy Example ===");
        ShoppingCart cart = new ShoppingCart();
        cart.addItem("Laptop");
        cart.addItem("Mouse");
        
        // 使用信用卡支付
        cart.setPaymentStrategy(new CreditCardPayment("John Doe", "1234567890123456"));
        cart.checkout(1200);
        
        System.out.println("\n=== New Purchase ===");
        cart.addItem("Book");
        cart.addItem("Pen");
        
        // 切换支付方式
        cart.setPaymentStrategy(new PayPalPayment("john.doe@example.com"));
        cart.checkout(50);
        
        System.out.println("\n=== Sorting Strategy Example ===");
        List<Integer> numbers = Arrays.asList(5, 2, 9, 1, 5, 6);
        Sorter sorter = new Sorter();
        
        sorter.setStrategy(new BubbleSort());
        sorter.sortList(new java.util.ArrayList<>(numbers));
        
        sorter.setStrategy(new QuickSort());
        sorter.sortList(new java.util.ArrayList<>(numbers));
        
        sorter.setStrategy(new MergeSort());
        sorter.sortList(new java.util.ArrayList<>(numbers));
    }
}

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

使用场景

  • 算法框架固定
  • 子步骤可变
  • 代码复用
  • 框架设计

解决问题

  • 算法骨架定义
  • 代码复用

优点

  • 代码复用
  • 提高扩展性
  • 符合开闭原则

缺点

  • 可能违反里氏替换原则
  • 增加系统复杂度
java 复制代码
// 抽象类
abstract class Game {
    protected abstract void initialize();
    protected abstract void startPlay();
    protected abstract void endPlay();
    
    // 模板方法
    public final void play() {
        // 初始化游戏
        initialize();
        
        // 开始游戏
        startPlay();
        
        // 结束游戏
        endPlay();
    }
}

// 具体类
class Cricket extends Game {
    @Override
    protected void initialize() {
        System.out.println("Cricket Game Initialized! Start playing.");
    }
    
    @Override
    protected void startPlay() {
        System.out.println("Cricket Game Started. Enjoy the game!");
    }
    
    @Override
    protected void endPlay() {
        System.out.println("Cricket Game Finished!");
    }
}

class Football extends Game {
    @Override
    protected void initialize() {
        System.out.println("Football Game Initialized! Start playing.");
    }
    
    @Override
    protected void startPlay() {
        System.out.println("Football Game Started. Enjoy the game!");
    }
    
    @Override
    protected void endPlay() {
        System.out.println("Football Game Finished!");
    }
}

// 数据处理器示例
abstract class DataProcessor {
    // 模板方法
    public final void process() {
        readData();
        processData();
        writeData();
    }
    
    protected abstract void readData();
    protected abstract void processData();
    
    protected void writeData() {
        System.out.println("Writing processed data...");
    }
}

class CSVDataProcessor extends DataProcessor {
    @Override
    protected void readData() {
        System.out.println("Reading data from CSV file...");
    }
    
    @Override
    protected void processData() {
        System.out.println("Processing CSV data...");
    }
}

class XMLDataProcessor extends DataProcessor {
    @Override
    protected void readData() {
        System.out.println("Reading data from XML file...");
    }
    
    @Override
    protected void processData() {
        System.out.println("Processing XML data...");
    }
    
    @Override
    protected void writeData() {
        System.out.println("Writing XML data to database...");
    }
}

class JSONDataProcessor extends DataProcessor {
    @Override
    protected void readData() {
        System.out.println("Reading data from JSON file...");
    }
    
    @Override
    protected void processData() {
        System.out.println("Processing JSON data...");
    }
    
    // 使用默认的writeData实现
}

// 使用钩子方法
abstract class Beverage {
    // 模板方法
    public final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {
            addCondiments();
        }
    }
    
    protected abstract void brew();
    protected abstract void addCondiments();
    
    protected void boilWater() {
        System.out.println("Boiling water");
    }
    
    protected void pourInCup() {
        System.out.println("Pouring into cup");
    }
    
    // 钩子方法 - 子类可以覆盖
    protected boolean customerWantsCondiments() {
        return true;
    }
}

class Coffee extends Beverage {
    @Override
    protected void brew() {
        System.out.println("Dripping coffee through filter");
    }
    
    @Override
    protected void addCondiments() {
        System.out.println("Adding sugar and milk");
    }
    
    @Override
    protected boolean customerWantsCondiments() {
        // 可以询问用户是否需要调料
        return true;
    }
}

class Tea extends Beverage {
    @Override
    protected void brew() {
        System.out.println("Steeping the tea");
    }
    
    @Override
    protected void addCondiments() {
        System.out.println("Adding lemon");
    }
    
    @Override
    protected boolean customerWantsCondiments() {
        // 茶默认不加调料
        return false;
    }
}

// 使用示例
public class TemplateMethodDemo {
    public static void main(String[] args) {
        System.out.println("=== Game Template Example ===");
        Game game = new Cricket();
        game.play();
        System.out.println();
        
        game = new Football();
        game.play();
        
        System.out.println("\n=== Data Processor Template Example ===");
        DataProcessor processor = new CSVDataProcessor();
        processor.process();
        System.out.println();
        
        processor = new XMLDataProcessor();
        processor.process();
        System.out.println();
        
        processor = new JSONDataProcessor();
        processor.process();
        
        System.out.println("\n=== Beverage Template with Hook Example ===");
        Beverage coffee = new Coffee();
        System.out.println("Preparing coffee:");
        coffee.prepareRecipe();
        System.out.println();
        
        Beverage tea = new Tea();
        System.out.println("Preparing tea:");
        tea.prepareRecipe();
    }
}

23. 访问者模式(Visitor)

使用场景

  • 对象结构稳定
  • 需要多种操作
  • 数据结构与操作分离
  • 编译器语法树

解决问题

  • 添加新操作
  • 数据结构和操作解耦

优点

  • 增加新操作容易
  • 相关行为集中
  • 符合单一职责原则

缺点

  • 增加新元素困难
  • 破坏封装性
java 复制代码
import java.util.ArrayList;
import java.util.List;

// 元素接口
interface ComputerPart {
    void accept(ComputerPartVisitor visitor);
}

// 具体元素
class Keyboard implements ComputerPart {
    @Override
    public void accept(ComputerPartVisitor visitor) {
        visitor.visit(this);
    }
}

class Monitor implements ComputerPart {
    @Override
    public void accept(ComputerPartVisitor visitor) {
        visitor.visit(this);
    }
}

class Mouse implements ComputerPart {
    @Override
    public void accept(ComputerPartVisitor visitor) {
        visitor.visit(this);
    }
}

class Computer implements ComputerPart {
    private List<ComputerPart> parts;
    
    public Computer() {
        parts = new ArrayList<>();
        parts.add(new Mouse());
        parts.add(new Keyboard());
        parts.add(new Monitor());
    }
    
    @Override
    public void accept(ComputerPartVisitor visitor) {
        for (ComputerPart part : parts) {
            part.accept(visitor);
        }
        visitor.visit(this);
    }
}

// 访问者接口
interface ComputerPartVisitor {
    void visit(Computer computer);
    void visit(Mouse mouse);
    void visit(Keyboard keyboard);
    void visit(Monitor monitor);
}

// 具体访问者
class ComputerPartDisplayVisitor implements ComputerPartVisitor {
    @Override
    public void visit(Computer computer) {
        System.out.println("Displaying Computer");
    }
    
    @Override
    public void visit(Mouse mouse) {
        System.out.println("Displaying Mouse");
    }
    
    @Override
    public void visit(Keyboard keyboard) {
        System.out.println("Displaying Keyboard");
    }
    
    @Override
    public void visit(Monitor monitor) {
        System.out.println("Displaying Monitor");
    }
}

class ComputerPartMaintenanceVisitor implements ComputerPartVisitor {
    @Override
    public void visit(Computer computer) {
        System.out.println("Maintaining Computer");
    }
    
    @Override
    public void visit(Mouse mouse) {
        System.out.println("Cleaning Mouse");
    }
    
    @Override
    public void visit(Keyboard keyboard) {
        System.out.println("Cleaning Keyboard");
    }
    
    @Override
    public void visit(Monitor monitor) {
        System.out.println("Cleaning Monitor screen");
    }
}

class ComputerPartDiagnosticVisitor implements ComputerPartVisitor {
    @Override
    public void visit(Computer computer) {
        System.out.println("Running diagnostics on Computer");
    }
    
    @Override
    public void visit(Mouse mouse) {
        System.out.println("Testing Mouse connectivity");
    }
    
    @Override
    public void visit(Keyboard keyboard) {
        System.out.println("Testing Keyboard keys");
    }
    
    @Override
    public void visit(Monitor monitor) {
        System.out.println("Testing Monitor display");
    }
}

// 表达式示例
interface Expression {
    void accept(ExpressionVisitor visitor);
}

class NumberExpression implements Expression {
    private int number;
    
    public NumberExpression(int number) {
        this.number = number;
    }
    
    public int getNumber() {
        return number;
    }
    
    @Override
    public void accept(ExpressionVisitor visitor) {
        visitor.visit(this);
    }
}

class AdditionExpression implements Expression {
    private Expression left;
    private Expression right;
    
    public AdditionExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }
    
    public Expression getLeft() {
        return left;
    }
    
    public Expression getRight() {
        return right;
    }
    
    @Override
    public void accept(ExpressionVisitor visitor) {
        visitor.visit(this);
    }
}

interface ExpressionVisitor {
    void visit(NumberExpression number);
    void visit(AdditionExpression addition);
}

class ExpressionEvaluator implements ExpressionVisitor {
    private int result;
    
    public int getResult() {
        return result;
    }
    
    @Override
    public void visit(NumberExpression number) {
        result = number.getNumber();
    }
    
    @Override
    public void visit(AdditionExpression addition) {
        // 递归计算左右表达式
        ExpressionEvaluator leftEval = new ExpressionEvaluator();
        addition.getLeft().accept(leftEval);
        
        ExpressionEvaluator rightEval = new ExpressionEvaluator();
        addition.getRight().accept(rightEval);
        
        result = leftEval.getResult() + rightEval.getResult();
    }
}

class ExpressionPrinter implements ExpressionVisitor {
    private StringBuilder sb = new StringBuilder();
    
    public String getExpression() {
        return sb.toString();
    }
    
    @Override
    public void visit(NumberExpression number) {
        sb.append(number.getNumber());
    }
    
    @Override
    public void visit(AdditionExpression addition) {
        sb.append("(");
        addition.getLeft().accept(this);
        sb.append(" + ");
        addition.getRight().accept(this);
        sb.append(")");
    }
}

// 使用示例
public class VisitorDemo {
    public static void main(String[] args) {
        System.out.println("=== Computer Parts Visitor Example ===");
        ComputerPart computer = new Computer();
        
        System.out.println("1. Display Visitor:");
        computer.accept(new ComputerPartDisplayVisitor());
        
        System.out.println("\n2. Maintenance Visitor:");
        computer.accept(new ComputerPartMaintenanceVisitor());
        
        System.out.println("\n3. Diagnostic Visitor:");
        computer.accept(new ComputerPartDiagnosticVisitor());
        
        System.out.println("\n=== Expression Visitor Example ===");
        // 创建表达式: (5 + 3) + 2
        Expression expression = new AdditionExpression(
            new AdditionExpression(
                new NumberExpression(5),
                new NumberExpression(3)
            ),
            new NumberExpression(2)
        );
        
        // 求值访问者
        ExpressionEvaluator evaluator = new ExpressionEvaluator();
        expression.accept(evaluator);
        System.out.println("Result: " + evaluator.getResult());
        
        // 打印访问者
        ExpressionPrinter printer = new ExpressionPrinter();
        expression.accept(printer);
        System.out.println("Expression: " + printer.getExpression());
    }
}

总结

设计模式是解决特定问题的可复用方案,每种模式都有其适用场景和优缺点:

创建型模式重点:

  • 单例:全局唯一实例
  • 工厂:对象创建解耦
  • 建造者:复杂对象构建
  • 原型:对象克隆

结构型模式重点:

  • 适配器:接口转换
  • 装饰器:动态添加功能
  • 代理:控制访问
  • 组合:树形结构

行为型模式重点:

  • 观察者:一对多依赖
  • 策略:算法切换
  • 模板方法:算法框架
  • 状态:状态驱动行为

选择原则:

  1. 理解问题本质:先分析问题,再选择模式
  2. 保持简单:不要过度设计
  3. 考虑变化:识别可能变化的部分
  4. 组合使用:模式可以组合使用

实际应用建议:

  • 从简单实现开始,需要时再重构
  • 优先使用组合而非继承
  • 保持代码可读性和可维护性
  • 理解模式思想比机械套用更重要

这些模式是经验的总结,掌握它们能帮助设计出更灵活、可维护的软件系统。在实际开发中,应根据具体需求灵活选择和调整模式实现。

相关推荐
alibli7 小时前
一文学会设计模式之结构型模式及最佳实现
c++·设计模式
电子科技圈10 小时前
SiFive车规级RISC-V IP获IAR最新版嵌入式开发工具全面支持,加速汽车电子创新
嵌入式硬件·tcp/ip·设计模式·汽车·代码规范·risc-v·代码复审
七月丶12 小时前
Cloudflare 🌏 中国大陆网络访问优化 - 0元成本
人工智能·react.js·设计模式
筏.k12 小时前
C++ 设计模式系列:单例模式
c++·单例模式·设计模式
__万波__12 小时前
二十三种设计模式(十二)--代理模式
java·设计模式·代理模式
郝学胜-神的一滴13 小时前
Linux线程编程:从原理到实践
linux·服务器·开发语言·c++·程序人生·设计模式·软件工程
我爱学习_zwj13 小时前
前端设计模式:轻量级实战指南
设计模式·前端框架·状态模式
还是大剑师兰特13 小时前
前端设计模式:详解、应用场景与核心对比
前端·设计模式·大剑师
平凡之路无尽路1 天前
智能体设计模式:构建智能系统的实践指南
人工智能·设计模式·自然语言处理·nlp·aigc·vllm