大数据

Java 23种设计模式

一、创建型模式 (5种)

1. 单例模式 (Singleton)

意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

/**
 * 单例模式 - 懒汉式(线程安全)
 */
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;
    }
    
    // 其他方法
    public void showMessage() {
        System.out.println("Hello, I am a Singleton!");
    }
}

// 使用示例
public class SingletonDemo {
    public static void main(String[] args) {
        // 获取单例对象
        Singleton singleton = Singleton.getInstance();
        // 调用方法
        singleton.showMessage();
        
        // 再次获取实例,验证是否为同一个对象
        Singleton anotherSingleton = Singleton.getInstance();
        System.out.println("Is same instance? " + (singleton == anotherSingleton));
    }
}

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

意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。

/**
 * 产品接口
 */
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 - 生产产品A
 */
class ConcreteFactoryA implements Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }
}

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

// 使用示例
public class FactoryMethodDemo {
    public static void main(String[] args) {
        // 创建工厂A
        Factory factoryA = new ConcreteFactoryA();
        // 使用工厂A创建产品
        Product productA = factoryA.createProduct();
        productA.use();
        
        // 创建工厂B
        Factory factoryB = new ConcreteFactoryB();
        // 使用工厂B创建产品
        Product productB = factoryB.createProduct();
        productB.use();
    }
}

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

意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

/**
 * 抽象产品A
 */
interface AbstractProductA {
    void use();
}

/**
 * 抽象产品B
 */
interface AbstractProductB {
    void eat();
}

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

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

/**
 * 具体产品B1
 */
class ProductB1 implements AbstractProductB {
    @Override
    public void eat() {
        System.out.println("Eating Product B1");
    }
}

/**
 * 具体产品B2
 */
class ProductB2 implements AbstractProductB {
    @Override
    public void eat() {
        System.out.println("Eating Product B2");
    }
}

/**
 * 抽象工厂
 */
interface AbstractFactory {
    AbstractProductA createProductA();
    AbstractProductB createProductB();
}

/**
 * 具体工厂1 - 生产A1和B1产品
 */
class ConcreteFactory1 implements AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ProductA1();
    }
    
    @Override
    public AbstractProductB createProductB() {
        return new ProductB1();
    }
}

/**
 * 具体工厂2 - 生产A2和B2产品
 */
class ConcreteFactory2 implements AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ProductA2();
    }
    
    @Override
    public AbstractProductB createProductB() {
        return new ProductB2();
    }
}

// 使用示例
public class AbstractFactoryDemo {
    public static void main(String[] args) {
        // 创建工厂1
        AbstractFactory factory1 = new ConcreteFactory1();
        // 使用工厂1创建产品A和B
        AbstractProductA productA1 = factory1.createProductA();
        AbstractProductB productB1 = factory1.createProductB();
        productA1.use();
        productB1.eat();
        
        // 创建工厂2
        AbstractFactory factory2 = new ConcreteFactory2();
        // 使用工厂2创建产品A和B
        AbstractProductA productA2 = factory2.createProductA();
        AbstractProductB productB2 = factory2.createProductB();
        productA2.use();
        productB2.eat();
    }
}

4. 建造者模式 (Builder)

意图:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

/**
 * 产品类 - 电脑
 */
class Computer {
    private String cpu;
    private String ram;
    private String storage;
    private String gpu;
    
    public void setCpu(String cpu) {
        this.cpu = cpu;
    }
    
    public void setRam(String ram) {
        this.ram = ram;
    }
    
    public void setStorage(String storage) {
        this.storage = storage;
    }
    
    public void setGpu(String gpu) {
        this.gpu = gpu;
    }
    
    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", ram='" + ram + '\'' +
                ", storage='" + storage + '\'' +
                ", gpu='" + gpu + '\'' +
                '}';
    }
}

/**
 * 抽象建造者
 */
interface ComputerBuilder {
    void buildCpu();
    void buildRam();
    void buildStorage();
    void buildGpu();
    Computer getResult();
}

/**
 * 具体建造者 - 游戏电脑
 */
class GamingComputerBuilder implements ComputerBuilder {
    private Computer computer = new Computer();
    
    @Override
    public void buildCpu() {
        computer.setCpu("Intel i9");
    }
    
    @Override
    public void buildRam() {
        computer.setRam("32GB DDR4");
    }
    
    @Override
    public void buildStorage() {
        computer.setStorage("1TB SSD + 2TB HDD");
    }
    
    @Override
    public void buildGpu() {
        computer.setGpu("NVIDIA RTX 3080");
    }
    
    @Override
    public Computer getResult() {
        return computer;
    }
}

/**
 * 具体建造者 - 办公电脑
 */
class OfficeComputerBuilder implements ComputerBuilder {
    private Computer computer = new Computer();
    
    @Override
    public void buildCpu() {
        computer.setCpu("Intel i5");
    }
    
    @Override
    public void buildRam() {
        computer.setRam("16GB DDR4");
    }
    
    @Override
    public void buildStorage() {
        computer.setStorage("512GB SSD");
    }
    
    @Override
    public void buildGpu() {
        computer.setGpu("Integrated Graphics");
    }
    
    @Override
    public Computer getResult() {
        return computer;
    }
}

/**
 * 指挥者
 */
class ComputerDirector {
    public Computer construct(ComputerBuilder builder) {
        builder.buildCpu();
        builder.buildRam();
        builder.buildStorage();
        builder.buildGpu();
        return builder.getResult();
    }
}

// 使用示例
public class BuilderDemo {
    public static void main(String[] args) {
        ComputerDirector director = new ComputerDirector();
        
        // 构建游戏电脑
        ComputerBuilder gamingBuilder = new GamingComputerBuilder();
        Computer gamingComputer = director.construct(gamingBuilder);
        System.out.println("Gaming Computer: " + gamingComputer);
        
        // 构建办公电脑
        ComputerBuilder officeBuilder = new OfficeComputerBuilder();
        Computer officeComputer = director.construct(officeBuilder);
        System.out.println("Office Computer: " + officeComputer);
    }
}

5. 原型模式 (Prototype)

意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

import java.util.HashMap;
import java.util.Map;

/**
 * 抽象原型类
 */
abstract class Shape implements Cloneable {
    private String id;
    protected String type;
    
    abstract void draw();
    
    public String getType() {
        return type;
    }
    
    public String getId() {
        return id;
    }
    
    public void setId(String id) {
        this.id = id;
    }
    
    @Override
    public Object clone() {
        Object clone = null;
        try {
            clone = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }
}

/**
 * 具体原型类 - 矩形
 */
class Rectangle extends Shape {
    public Rectangle() {
        type = "Rectangle";
    }
    
    @Override
    public void draw() {
        System.out.println("Inside Rectangle::draw() method.");
    }
}

/**
 * 具体原型类 - 圆形
 */
class Circle extends Shape {
    public Circle() {
        type = "Circle";
    }
    
    @Override
    public void draw() {
        System.out.println("Inside Circle::draw() method.");
    }
}

/**
 * 原型管理器
 */
class ShapeCache {
    private static Map<String, Shape> shapeMap = new HashMap<>();
    
    public static Shape getShape(String shapeId) {
        Shape cachedShape = shapeMap.get(shapeId);
        return (Shape) cachedShape.clone();
    }
    
    // 对每种形状都运行数据库查询,并创建该形状
    // shapeMap.put(shapeKey, shape);
    // 例如,我们要添加三种形状
    public static void loadCache() {
        Circle circle = new Circle();
        circle.setId("1");
        shapeMap.put(circle.getId(), circle);
        
        Rectangle rectangle = new Rectangle();
        rectangle.setId("2");
        shapeMap.put(rectangle.getId(), rectangle);
    }
}

// 使用示例
public class PrototypeDemo {
    public static void main(String[] args) {
        ShapeCache.loadCache();
        
        Shape clonedShape1 = ShapeCache.getShape("1");
        System.out.println("Shape : " + clonedShape1.getType());
        clonedShape1.draw();
        
        Shape clonedShape2 = ShapeCache.getShape("2");
        System.out.println("Shape : " + clonedShape2.getType());
        clonedShape2.draw();
        
        // 验证是否为不同对象
        System.out.println("Are shapes same? " + (clonedShape1 == clonedShape2));
    }
}

二、结构型模式 (7种)

6. 适配器模式 (Adapter)

意图:将一个类的接口转换成客户希望的另外一个接口。

/**
 * 目标接口 - 客户期望的接口
 */
interface MediaPlayer {
    void play(String audioType, String fileName);
}

/**
 * 适配者接口 - 已存在的接口
 */
interface AdvancedMediaPlayer {
    void playVlc(String fileName);
    void playMp4(String fileName);
}

/**
 * 具体适配者 - VLC播放器
 */
class VlcPlayer implements AdvancedMediaPlayer {
    @Override
    public void playVlc(String fileName) {
        System.out.println("Playing vlc file. Name: " + fileName);
    }
    
    @Override
    public void playMp4(String fileName) {
        // 什么也不做
    }
}

/**
 * 具体适配者 - MP4播放器
 */
class Mp4Player implements AdvancedMediaPlayer {
    @Override
    public void playVlc(String fileName) {
        // 什么也不做
    }
    
    @Override
    public void playMp4(String fileName) {
        System.out.println("Playing mp4 file. Name: " + 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. Name: " + fileName);
        }
        // mediaAdapter 提供了播放其他文件格式的支持
        else if (audioType.equalsIgnoreCase("vlc") 
                || audioType.equalsIgnoreCase("mp4")) {
            mediaAdapter = new MediaAdapter(audioType);
            mediaAdapter.play(audioType, fileName);
        } else {
            System.out.println("Invalid media. " + audioType + " format not supported");
        }
    }
}

// 使用示例
public class AdapterDemo {
    public static void main(String[] args) {
        AudioPlayer audioPlayer = new AudioPlayer();
        
        audioPlayer.play("mp3", "beyond the horizon.mp3");
        audioPlayer.play("mp4", "alone.mp4");
        audioPlayer.play("vlc", "far far away.vlc");
        audioPlayer.play("avi", "mind me.avi");
    }
}

7. 桥接模式 (Bridge)

意图:将抽象部分与它的实现部分分离,使它们都可以独立地变化。

/**
 * 实现部分接口
 */
interface DrawAPI {
    void drawCircle(int radius, int x, int y);
}

/**
 * 具体实现A
 */
class RedCircle implements DrawAPI {
    @Override
    public void drawCircle(int radius, int x, int y) {
        System.out.println("Drawing Circle[ color: red, radius: " 
                + radius + ", x: " + x + ", y: " + y + "]");
    }
}

/**
 * 具体实现B
 */
class GreenCircle implements DrawAPI {
    @Override
    public void drawCircle(int radius, int x, int y) {
        System.out.println("Drawing Circle[ color: green, radius: " 
                + radius + ", x: " + x + ", y: " + y + "]");
    }
}

/**
 * 抽象部分
 */
abstract class Shape {
    protected DrawAPI drawAPI;
    
    protected Shape(DrawAPI drawAPI) {
        this.drawAPI = drawAPI;
    }
    
    public abstract void draw();
}

/**
 * 扩展抽象部分 - 圆形
 */
class Circle extends Shape {
    private int x, y, radius;
    
    public Circle(int x, int y, int radius, DrawAPI drawAPI) {
        super(drawAPI);
        this.x = x;
        this.y = y;
        this.radius = radius;
    }
    
    @Override
    public void draw() {
        drawAPI.drawCircle(radius, x, y);
    }
}

// 使用示例
public class BridgeDemo {
    public static void main(String[] args) {
        Shape redCircle = new Circle(100, 100, 10, new RedCircle());
        Shape greenCircle = new Circle(200, 200, 20, new GreenCircle());
        
        redCircle.draw();
        greenCircle.draw();
    }
}

8. 组合模式 (Composite)

意图:将对象组合成树形结构以表示"部分-整体"的层次结构。

import java.util.ArrayList;
import java.util.List;

/**
 * 组件接口
 */
interface Employee {
    void showEmployeeDetails();
}

/**
 * 叶子节点 - 开发人员
 */
class Developer implements Employee {
    private String name;
    private String position;
    
    public Developer(String name, String position) {
        this.name = name;
        this.position = position;
    }
    
    @Override
    public void showEmployeeDetails() {
        System.out.println("Developer: " + name + ", Position: " + position);
    }
}

/**
 * 叶子节点 - 经理
 */
class Manager implements Employee {
    private String name;
    private String position;
    
    public Manager(String name, String position) {
        this.name = name;
        this.position = position;
    }
    
    @Override
    public void showEmployeeDetails() {
        System.out.println("Manager: " + name + ", Position: " + position);
    }
}

/**
 * 组合类 - 部门
 */
class Department implements Employee {
    private String name;
    private List<Employee> employees = new ArrayList<>();
    
    public Department(String name) {
        this.name = name;
    }
    
    public void addEmployee(Employee employee) {
        employees.add(employee);
    }
    
    public void removeEmployee(Employee employee) {
        employees.remove(employee);
    }
    
    @Override
    public void showEmployeeDetails() {
        System.out.println("Department: " + name);
        for (Employee employee : employees) {
            employee.showEmployeeDetails();
        }
    }
}

// 使用示例
public class CompositeDemo {
    public static void main(String[] args) {
        Employee dev1 = new Developer("John", "Senior Developer");
        Employee dev2 = new Developer("David", "Junior Developer");
        
        Department engineering = new Department("Engineering");
        engineering.addEmployee(dev1);
        engineering.addEmployee(dev2);
        
        Employee man1 = new Manager("Mike", "Engineering Manager");
        Employee man2 = new Manager("Sophia", "HR Manager");
        
        Department hr = new Department("Human Resources");
        hr.addEmployee(man2);
        
        Department company = new Department("Company");
        company.addEmployee(man1);
        company.addEmployee(engineering);
        company.addEmployee(hr);
        
        company.showEmployeeDetails();
    }
}

9. 装饰器模式 (Decorator)

意图:动态地给一个对象添加一些额外的职责。

/**
 * 组件接口
 */
interface Car {
    void assemble();
}

/**
 * 具体组件
 */
class BasicCar implements Car {
    @Override
    public void assemble() {
        System.out.print("Basic Car.");
    }
}

/**
 * 装饰器抽象类
 */
abstract class CarDecorator implements Car {
    protected Car car;
    
    public CarDecorator(Car car) {
        this.car = car;
    }
    
    @Override
    public void assemble() {
        car.assemble();
    }
}

/**
 * 具体装饰器 - 运动型
 */
class SportsCar extends CarDecorator {
    public SportsCar(Car car) {
        super(car);
    }
    
    @Override
    public void assemble() {
        super.assemble();
        System.out.print(" Adding features of Sports Car.");
    }
}

/**
 * 具体装饰器 - 豪华型
 */
class LuxuryCar extends CarDecorator {
    public LuxuryCar(Car car) {
        super(car);
    }
    
    @Override
    public void assemble() {
        super.assemble();
        System.out.print(" Adding features of Luxury Car.");
    }
}

// 使用示例
public class DecoratorDemo {
    public static void main(String[] args) {
        Car sportsCar = new SportsCar(new BasicCar());
        sportsCar.assemble();
        System.out.println("\n");
        
        Car sportsLuxuryCar = new SportsCar(new LuxuryCar(new BasicCar()));
        sportsLuxuryCar.assemble();
    }
}

10. 外观模式 (Facade)

意图:为子系统中的一组接口提供一个一致的界面。

/**
 * 子系统A
 */
class CPU {
    public void freeze() {
        System.out.println("CPU freeze");
    }
    
    public void jump(long position) {
        System.out.println("CPU jump to " + position);
    }
    
    public void execute() {
        System.out.println("CPU execute");
    }
}

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

/**
 * 子系统C
 */
class HardDrive {
    public byte[] read(long lba, int size) {
        System.out.println("HardDrive read " + size + " bytes from " + lba);
        return new byte[size];
    }
}

/**
 * 外观类
 */
class ComputerFacade {
    private static final long BOOT_ADDRESS = 0x00000000;
    private static final long BOOT_SECTOR = 0x00000000;
    private static final int SECTOR_SIZE = 512;
    
    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() {
        processor.freeze();
        ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE));
        processor.jump(BOOT_ADDRESS);
        processor.execute();
    }
}

// 使用示例
public class FacadeDemo {
    public static void main(String[] args) {
        ComputerFacade computer = new ComputerFacade();
        computer.start();
    }
}

11. 享元模式 (Flyweight)

意图:运用共享技术有效地支持大量细粒度的对象。

import java.util.HashMap;

/**
 * 享元接口
 */
interface Shape {
    void draw();
}

/**
 * 具体享元类
 */
class Circle implements Shape {
    private String color;
    private int x;
    private int y;
    private int radius;
    
    public Circle(String color) {
        this.color = color;
    }
    
    public void setX(int x) {
        this.x = x;
    }
    
    public void setY(int y) {
        this.y = y;
    }
    
    public void setRadius(int radius) {
        this.radius = radius;
    }
    
    @Override
    public void draw() {
        System.out.println("Circle: Draw() [Color : " + color 
                + ", x : " + x + ", y :" + y + ", radius :" + radius);
    }
}

/**
 * 享元工厂
 */
class ShapeFactory {
    private static final HashMap<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 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.setX(getRandomX());
            circle.setY(getRandomY());
            circle.setRadius(100);
            circle.draw();
        }
    }
    
    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)

意图:为其他对象提供一种代理以控制对这个对象的访问。

/**
 * 接口
 */
interface Image {
    void display();
}

/**
 * 真实对象
 */
class RealImage implements Image {
    private String fileName;
    
    public RealImage(String fileName) {
        this.fileName = fileName;
        loadFromDisk(fileName);
    }
    
    @Override
    public void display() {
        System.out.println("Displaying " + fileName);
    }
    
    private void loadFromDisk(String fileName) {
        System.out.println("Loading " + 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_10mb.jpg");
        
        // 图像将从磁盘加载
        image.display();
        System.out.println("");
        
        // 图像不需要从磁盘加载
        image.display();
    }
}

三、行为型模式 (11种)

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

意图:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。

/**
 * 抽象处理器
 */
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("Standard Console::Logger: " + message);
    }
}

/**
 * 具体处理器 - 错误日志
 */
class ErrorLogger extends Logger {
    public ErrorLogger(int level) {
        this.level = level;
    }
    
    @Override
    protected void write(String message) {
        System.out.println("Error 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);
    }
}

// 使用示例
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();
        
        loggerChain.logMessage(Logger.INFO, "This is an information.");
        System.out.println();
        
        loggerChain.logMessage(Logger.DEBUG, "This is a debug level information.");
        System.out.println();
        
        loggerChain.logMessage(Logger.ERROR, "This is an error information.");
    }
}

14. 命令模式 (Command)

意图:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。

/**
 * 命令接口
 */
interface Order {
    void execute();
}

/**
 * 请求类
 */
class Stock {
    private String name = "ABC";
    private int quantity = 10;
    
    public void buy() {
        System.out.println("Stock [ Name: " + name + ", Quantity: " 
                + quantity + " ] bought");
    }
    
    public void sell() {
        System.out.println("Stock [ Name: " + name + ", Quantity: " 
                + quantity + " ] sold");
    }
}

/**
 * 具体命令 - 买入
 */
class BuyStock implements Order {
    private Stock abcStock;
    
    public BuyStock(Stock abcStock) {
        this.abcStock = abcStock;
    }
    
    @Override
    public void execute() {
        abcStock.buy();
    }
}

/**
 * 具体命令 - 卖出
 */
class SellStock implements Order {
    private Stock abcStock;
    
    public SellStock(Stock abcStock) {
        this.abcStock = abcStock;
    }
    
    @Override
    public void execute() {
        abcStock.sell();
    }
}

/**
 * 调用者
 */
class Broker {
    private List<Order> orderList = new ArrayList<>();
    
    public void takeOrder(Order order) {
        orderList.add(order);
    }
    
    public void placeOrders() {
        for (Order order : orderList) {
            order.execute();
        }
        orderList.clear();
    }
}

// 使用示例
public class CommandDemo {
    public static void main(String[] args) {
        Stock abcStock = new Stock();
        
        BuyStock buyStockOrder = new BuyStock(abcStock);
        SellStock sellStockOrder = new SellStock(abcStock);
        
        Broker broker = new Broker();
        broker.takeOrder(buyStockOrder);
        broker.takeOrder(sellStockOrder);
        
        broker.placeOrders();
    }
}

15. 解释器模式 (Interpreter)

意图:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

import java.util.Stack;

/**
 * 表达式接口
 */
interface Expression {
    boolean interpret(String context);
}

/**
 * 终结符表达式
 */
class TerminalExpression implements Expression {
    private String data;
    
    public TerminalExpression(String data) {
        this.data = data;
    }
    
    @Override
    public boolean interpret(String context) {
        return context.contains(data);
    }
}

/**
 * 或表达式
 */
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(String context) {
        return expr1.interpret(context) || expr2.interpret(context);
    }
}

/**
 * 与表达式
 */
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(String context) {
        return expr1.interpret(context) && expr2.interpret(context);
    }
}

// 使用示例
public class InterpreterDemo {
    // 规则:Robert 和 John 是男性
    public static Expression getMaleExpression() {
        Expression robert = new TerminalExpression("Robert");
        Expression john = new TerminalExpression("John");
        return new OrExpression(robert, john);
    }
    
    // 规则:Julie 是一个已婚的女性
    public static Expression getMarriedWomanExpression() {
        Expression julie = new TerminalExpression("Julie");
        Expression married = new TerminalExpression("Married");
        return new AndExpression(julie, married);
    }
    
    public static void main(String[] args) {
        Expression isMale = getMaleExpression();
        Expression isMarriedWoman = getMarriedWomanExpression();
        
        System.out.println("John is male? " + isMale.interpret("John"));
        System.out.println("Julie is a married woman? " 
                + isMarriedWoman.interpret("Married Julie"));
    }
}

16. 迭代器模式 (Iterator)

意图:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。

/**
 * 迭代器接口
 */
interface Iterator {
    boolean hasNext();
    Object next();
}

/**
 * 容器接口
 */
interface Container {
    Iterator getIterator();
}

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

// 使用示例
public class IteratorDemo {
    public static void main(String[] args) {
        NameRepository namesRepository = new NameRepository();
        
        for (Iterator iter = namesRepository.getIterator(); iter.hasNext();) {
            String name = (String) iter.next();
            System.out.println("Name : " + name);
        }
    }
}

17. 中介者模式 (Mediator)

意图:用一个中介对象来封装一系列的对象交互。

import java.util.Date;

/**
 * 中介者接口
 */
interface ChatRoom {
    void showMessage(User user, String message);
}

/**
 * 具体中介者
 */
class ChatRoomImpl implements ChatRoom {
    @Override
    public void showMessage(User user, String message) {
        System.out.println(new Date().toString() + " [" + user.getName() + "] : " + message);
    }
}

/**
 * 同事类
 */
class User {
    private String name;
    private ChatRoom chatRoom;
    
    public User(String name, ChatRoom chatRoom) {
        this.name = name;
        this.chatRoom = chatRoom;
    }
    
    public String getName() {
        return name;
    }
    
    public void sendMessage(String message) {
        chatRoom.showMessage(this, message);
    }
}

// 使用示例
public class MediatorDemo {
    public static void main(String[] args) {
        ChatRoom chatRoom = new ChatRoomImpl();
        
        User john = new User("John", chatRoom);
        User jane = new User("Jane", chatRoom);
        
        john.sendMessage("Hi there!");
        jane.sendMessage("Hey!");
    }
}

18. 备忘录模式 (Memento)

意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

/**
 * 备忘录类
 */
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;
    }
    
    public String getState() {
        return state;
    }
    
    public Memento saveStateToMemento() {
        return new Memento(state);
    }
    
    public void getStateFromMemento(Memento memento) {
        state = memento.getState();
    }
}

/**
 * 管理者类
 */
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 class MementoDemo {
    public static void main(String[] args) {
        Originator originator = new Originator();
        CareTaker careTaker = new CareTaker();
        
        originator.setState("State #1");
        originator.setState("State #2");
        careTaker.add(originator.saveStateToMemento());
        
        originator.setState("State #3");
        careTaker.add(originator.saveStateToMemento());
        
        originator.setState("State #4");
        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)

意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

import java.util.ArrayList;
import java.util.List;

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

/**
 * 具体主题
 */
class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private int state;
    
    public int getState() {
        return state;
    }
    
    public void setState(int state) {
        this.state = state;
        notifyObservers();
    }
    
    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
    }
    
    @Override
    public void removeObserver(Observer o) {
        observers.remove(o);
    }
    
    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

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

/**
 * 具体观察者A
 */
class ConcreteObserverA implements Observer {
    private ConcreteSubject subject;
    
    public ConcreteObserverA(ConcreteSubject subject) {
        this.subject = subject;
        subject.registerObserver(this);
    }
    
    @Override
    public void update() {
        System.out.println("ConcreteObserverA: Subject's state changed to " 
                + subject.getState());
    }
}

/**
 * 具体观察者B
 */
class ConcreteObserverB implements Observer {
    private ConcreteSubject subject;
    
    public ConcreteObserverB(ConcreteSubject subject) {
        this.subject = subject;
        subject.registerObserver(this);
    }
    
    @Override
    public void update() {
        System.out.println("ConcreteObserverB: Subject's state changed to " 
                + subject.getState());
    }
}

// 使用示例
public class ObserverDemo {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();
        
        new ConcreteObserverA(subject);
        new ConcreteObserverB(subject);
        
        subject.setState(1);
        subject.setState(2);
    }
}

20. 状态模式 (State)

意图:允许一个对象在其内部状态改变时改变它的行为。

/**
 * 状态接口
 */
interface State {
    void doAction(Context context);
}

/**
 * 具体状态 - 开始状态
 */
class StartState implements State {
    @Override
    public void doAction(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 doAction(Context context) {
        System.out.println("Player is in stop state");
        context.setState(this);
    }
    
    @Override
    public String toString() {
        return "Stop State";
    }
}

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

// 使用示例
public class StateDemo {
    public static void main(String[] args) {
        Context context = new Context();
        
        StartState startState = new StartState();
        startState.doAction(context);
        System.out.println(context.getState().toString());
        
        StopState stopState = new StopState();
        stopState.doAction(context);
        System.out.println(context.getState().toString());
    }
}

21. 策略模式 (Strategy)

意图:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。

/**
 * 策略接口
 */
interface Strategy {
    int doOperation(int num1, int num2);
}

/**
 * 具体策略 - 加法
 */
class OperationAdd implements Strategy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 + num2;
    }
}

/**
 * 具体策略 - 减法
 */
class OperationSubtract implements Strategy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 - num2;
    }
}

/**
 * 具体策略 - 乘法
 */
class OperationMultiply implements Strategy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 * num2;
    }
}

/**
 * 上下文类
 */
class Context {
    private Strategy strategy;
    
    public Context(Strategy strategy) {
        this.strategy = strategy;
    }
    
    public int executeStrategy(int num1, int num2) {
        return strategy.doOperation(num1, num2);
    }
}

// 使用示例
public class StrategyDemo {
    public static void main(String[] args) {
        Context context = new Context(new OperationAdd());
        System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
        
        context = new Context(new OperationSubtract());
        System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
        
        context = new Context(new OperationMultiply());
        System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
    }
}

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

意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。

/**
 * 抽象类 - 定义模板方法
 */
abstract class Game {
    abstract void initialize();
    abstract void startPlay();
    abstract void endPlay();
    
    // 模板方法
    public final void play() {
        // 初始化游戏
        initialize();
        
        // 开始游戏
        startPlay();
        
        // 结束游戏
        endPlay();
    }
}

/**
 * 具体子类 - 足球游戏
 */
class Football extends Game {
    @Override
    void initialize() {
        System.out.println("Football Game Initialized! Start playing.");
    }
    
    @Override
    void startPlay() {
        System.out.println("Football Game Started. Enjoy the game!");
    }
    
    @Override
    void endPlay() {
        System.out.println("Football Game Finished!");
    }
}

/**
 * 具体子类 - 篮球游戏
 */
class Basketball extends Game {
    @Override
    void initialize() {
        System.out.println("Basketball Game Initialized! Start playing.");
    }
    
    @Override
    void startPlay() {
        System.out.println("Basketball Game Started. Enjoy the game!");
    }
    
    @Override
    void endPlay() {
        System.out.println("Basketball Game Finished!");
    }
}

// 使用示例
public class TemplateMethodDemo {
    public static void main(String[] args) {
        Game game = new Football();
        game.play();
        System.out.println();
        
        game = new Basketball();
        game.play();
    }
}

23. 访问者模式 (Visitor)

意图:表示一个作用于某对象结构中的各元素的操作。

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

/**
 * 具体元素 - 键盘
 */
class Keyboard implements ComputerPart {
    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
        computerPartVisitor.visit(this);
    }
}

/**
 * 具体元素 - 显示器
 */
class Monitor implements ComputerPart {
    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
        computerPartVisitor.visit(this);
    }
}

/**
 * 具体元素 - 鼠标
 */
class Mouse implements ComputerPart {
    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
        computerPartVisitor.visit(this);
    }
}

/**
 * 具体元素 - 计算机
 */
class Computer implements ComputerPart {
    ComputerPart[] parts;
    
    public Computer() {
        parts = new ComputerPart[] {new Mouse(), new Keyboard(), new Monitor()};
    }
    
    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
        for (ComputerPart part : parts) {
            part.accept(computerPartVisitor);
        }
        computerPartVisitor.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.");
    }
}

// 使用示例
public class VisitorDemo {
    public static void main(String[] args) {
        ComputerPart computer = new Computer();
        computer.accept(new ComputerPartDisplayVisitor());
    }
}

总结

这23种设计模式可以分为三大类:

  1. 创建型模式:关注对象的创建过程
    • 单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式
  2. 结构型模式:关注类和对象的组合
    • 适配器模式、桥接模式、组合模式、装饰器模式、外观模式、享元模式、代理模式
  3. 行为型模式:关注对象之间的交互
    • 责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式

每种设计模式都有其特定的应用场景,理解这些模式可以帮助我们编写更加灵活、可维护和可扩展的代码。在实际开发中,应根据具体问题选择合适的模式,而不是为了使用模式而使用模式。