构建设计模式字典

Posted on 2025-09-30 00:36  吾以观复  阅读(3)  评论(0)    收藏  举报

关联知识库:构建设计模式字典

设计模式字典 - 中文版

https://draveness.me/holy-grail-design-pattern/

https://www.cnblogs.com/wxdlut/p/17346906.html

https://developer.aliyun.com/article/342530

https://www.infoq.cn/article/design-patterns-proposed-by-gof-20-years-ago

关于设计模式的争议

近年来,关于设计模式的争论非常激烈。

理解和学习它是第一步(如果你想谈论它,无论你站在哪一边)。

站在巨人的肩膀上无疑是一个明智的选择。作为经验的汇集,无疑见证了前辈们是如何运用面向对象编程(OOP)思想的。这23篇经验汇集展现了一段辉煌的历史。

如何应用它是第二步,而分歧也由此而来。
有些人将设计模式奉为天堂,认为它们是最佳实践,并被广泛使用。
另一些人则将设计模式贬低为地狱,认为它们不过是过去的糟粕,并不适用于当下。
当然,大多数人持中立态度。

尽信书不如无书。追求低耦合,但不可能完全没有耦合。

首先,在实际应用中考虑使用设计模式并没有错。这只是利用现有的解决方案来解决现有的问题。

然而,在分析和处理问题时,并不应该局限于设计模式。设计模式是面向对象编程(OOP)思维的最佳实践,也就是说,OOP 的落地经验产生了设计模式。

面对实际问题时,OOP 思维应该是第一反应。在 OOP 思维下,问题才有一个对应的上下文。这些上下文就是设计模式的源泉。同时,可以考虑当前问题是否与设计模式中已经解决的问题相匹配。

OOP和设计模式的比喻:乘法规则 / 25*25 = 625

接下来,也是最重要的一步 —— 平衡 与取舍
这是把握设计与过度设计的关键一步,关键在于利大于弊

设计模式并不能解决所有问题,反而会带来新的问题。但如果解决问题的价值大于新问题的弊端,那就使用它。

这条规则似乎不仅限于设计模式,所有方法论都适用。动态地分析问题处理方式的优劣,是为了达到一个准确合理的终点。

创建对象的模式

单例模式

全局唯一;通过添加类似 @Component 的注解,Spring bean 的作用域为单例。

原型模式

通过复制旧对象创建对象;为 Spring bean 设置 @Scope("prototype")。

建造者模式

使用建造者模式创建复杂对象,无需在构造函数中传递大量参数;为对象添加 Lombok 的 @Builder 注解。

工厂模式

封装一组或多组对象的创建过程,并提供统一的参数化对象创建入口。[结合策略模式实现]

  • 工厂方法
  • 抽象工厂 —— 工厂的工厂

对象行为模式

策略模式

背景:对于对象的单一行为,在不同场景下会有不同的实现。

思路:添加策略层(策略接口),解耦程序调用与实现,实现程序的可扩展性。

Implemention: https://github.com/qiao-925/Strategy-pattern-demo

模板模式

背景:对于一组操作,大多数步骤相同,只有少数步骤不同,这将产生大量重复代码。

思路:定义程序的框架,并将部分步骤推迟到子类中,以实现模板代码复用。

观察者模式

对象级别的 MQ。

专注于对象级别的事件发布和消息通知

职责链模式

根据单一职责原则,将复杂的业务处理流程拆分成链表结构,以实现可读性和可扩展性。

命令模式

解耦请求发送者和接收者。

  • code example

    // 命令接口
    public interface Command {
        void execute();
    }
    
    // 接收者
    public class Light {
        public void turnOn() {
            System.out.println("The light is on.");
        }
    
        public void turnOff() {
            System.out.println("The light is off.");
        }
    }
    
    // 具体命令:打开灯
    public class TurnOnLightCommand implements Command {
        private Light light;
    
        public TurnOnLightCommand(Light light) {
            this.light = light;
        }
    
        @Override
        public void execute() {
            light.turnOn();
        }
    }
    
    // 具体命令:关闭灯
    public class TurnOffLightCommand implements Command {
        private Light light;
    
        public TurnOffLightCommand(Light light) {
            this.light = light;
        }
    
        @Override
        public void execute() {
            light.turnOff();
        }
    }
    
    // 调用者
    public class RemoteControl {
        private Command command;
    
        public void setCommand(Command command) {
            this.command = command;
        }
    
        public void pressButton() {
            command.execute(); // 执行命令
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            Light light = new Light(); // 创建接收者
            Command turnOn = new TurnOnLightCommand(light); // 创建打开灯的命令
            Command turnOff = new TurnOffLightCommand(light); // 创建关闭灯的命令
    
            RemoteControl remote = new RemoteControl(); // 创建调用者
    
            // 打开灯
            remote.setCommand(turnOn);
            remote.pressButton();
    
            // 关闭灯
            remote.setCommand(turnOff);
            remote.pressButton();
        }
    }
    

备忘录模式

目标:用于对象的历史记录和备份。

示例:用于编辑器,记录和恢复历史状态。

  • code example

    public class Originator {
        private String state;
    
        public Originator(String state) {
            this.state = state;
        }
    
        public String getState() {
            return state;
        }
    
        public void setState(String state) {
            this.state = state;
        }
    /**
    * right here
    **/
        **public Memento createMemento() {
            return new Memento(state);
        }
    
        public void restoreMemento(Memento memento) {
            this.state = memento.getState();
        }**
    
        // Inner class for Memento
        public static class Memento {
            private final String state;
    
            public Memento(String state) {
                this.state = state;
            }
    
            public String getState() {
                return state;
            }
        }
    }
    

关于此模式,讨论的是:

如何在不破坏封装性的情况下公开私有成员变量数据?

当然,从私有变为公共很容易,但这会破坏封装性。

解决方案:对象本身保留创建备份的功能。

顺便说一句,这与充血模型的思维相关。

备忘录模式和充血模型比较 —— from manus

https://refactoringguru.cn/design-patterns/memento

状态模式

为每个状态及其行为创建类,以减少超过 3 个“if/else”语句的复杂性。

更易读、更易于维护,但类太多。

  • comparation

    normal implemention:

    public class ContentWithoutState {
        private String status = "草稿"; // 初始状态为草稿
    
        public void publish() {
            if (status.equals("草稿")) {
                status = "待发布";
                System.out.println("内容已提交待发布");
            } else if (status.equals("待发布")) {
                // 模拟发布过程,可能成功或失败
                boolean success = Math.random() < 0.8; // 80%概率成功
                if (success) {
                    status = "已发布";
                    System.out.println("内容发布成功");
                } else {
                    status = "发布失败";
                    System.out.println("内容发布失败");
                }
            } else {
                System.out.println("内容状态不允许发布");
            }
        }
    
        public String getStatus() {
            return status;
        }
    
        public static void main(String[] args) {
            ContentWithoutState content = new ContentWithoutState();
            content.publish();
            System.out.println("当前状态: " + content.getStatus());
            content.publish();
            System.out.println("当前状态: " + content.getStatus());
            content.publish();
            System.out.println("当前状态: " + content.getStatus());
        }
    }
    

    implementiom by state pattern

    interface ContentStatus {
        void publish(Content content);
    }
    
    class DraftStatus implements ContentStatus {
        @Override
        public void publish(Content content) {
            System.out.println("内容已提交待发布");
            content.setStatus(content.getPendingStatus());
        }
    }
    
    class PendingStatus implements ContentStatus {
        @Override
        public void publish(Content content) {
            boolean success = Math.random() < 0.8; // 80%概率成功
            if (success) {
                System.out.println("内容发布成功");
                content.setStatus(content.getPublishedStatus());
            } else {
                System.out.println("内容发布失败");
                content.setStatus(content.getFailedStatus());
            }
        }
    }
    
    class PublishedStatus implements ContentStatus {
        @Override
        public void publish(Content content) {
            System.out.println("内容已发布,无法再次发布");
        }
    }
    
    class FailedStatus implements ContentStatus {
        @Override
        public void publish(Content content) {
            System.out.println("内容发布失败,请检查错误并重新提交");
        }
    }
    
    public class ContentWithState {
        private ContentStatus status;
        private DraftStatus draftStatus = new DraftStatus();
        private PendingStatus pendingStatus = new PendingStatus();
        private PublishedStatus publishedStatus = new PublishedStatus();
        private FailedStatus failedStatus = new FailedStatus();
    
        public ContentWithState() {
            this.status = draftStatus;
        }
    
        public void publish() {
            status.publish(this);
        }
    
        public void setStatus(ContentStatus status) {
            this.status = status;
        }
    
        public ContentStatus getDraftStatus() { return draftStatus; }
        public ContentStatus getPendingStatus() { return pendingStatus; }
        public ContentStatus getPublishedStatus() { return publishedStatus; }
        public ContentStatus getFailedStatus() { return failedStatus; }
    
        public static void main(String[] args) {
            ContentWithState content = new ContentWithState();
            content.publish();
            content.publish();
            content.publish();
        }
    }
    

访问者模式

将数据结构与作用于它们的算法分离。

  • Example by json operations:

    import org.json.JSONObject;
    
    interface JsonVisitor {
        void visit(JSONObject jsonObject);
    }
    
    class PrintJsonVisitor implements JsonVisitor {
        @Override
        public void visit(JSONObject jsonObject) {
            System.out.println("Name: " + jsonObject.getString("name"));
            System.out.println("Age: " + jsonObject.getInt("age"));
            System.out.println("City: " + jsonObject.getString("city"));
        }
    }
    
    class AgeSquareJsonVisitor implements JsonVisitor {
        @Override
        public void visit(JSONObject jsonObject) {
            int age = jsonObject.getInt("age");
            System.out.println("Age squared: " + age * age);
        }
    }
    
    class AgePlusTenJsonVisitor implements JsonVisitor {
        @Override
        public void visit(JSONObject jsonObject) {
            int age = jsonObject.getInt("age");
            System.out.println("Age plus 10: " + (age + 10));
        }
    }
    
    public class JsonWithVisitor {
        public static void main(String[] args) {
            String jsonString = "{\"name\":\"Alice\",\"age\":30,\"city\":\"New York\"}";
            JSONObject jsonObject = new JSONObject(jsonString);
    
            JsonVisitor printVisitor = new PrintJsonVisitor();
            printVisitor.visit(jsonObject);
    
            JsonVisitor ageSquareVisitor = new AgeSquareJsonVisitor();
            ageSquareVisitor.visit(jsonObject);
    
            JsonVisitor agePlusTenVisitor = new AgePlusTenJsonVisitor();
            agePlusTenVisitor.visit(jsonObject);
        }
    }
    

中介者模式

背景:多个对象之间存在大量的相互依赖关系。

其理念与 IOC 非常相似:将对象之间的对话转换为中介者与对象之间的对话。

对象结构模式

适配器模式

添加适配层来解决接口不兼容问题。

专注于接口层面。

桥接模式

延迟实例化和绑定。

使用组合模式代替继承模式,以避免类的排列组合导致的数量激增。

```jsx
// Implementor interface
interface MessageSender {
    void sendMessage(String message);
}

// Concrete Implementors
class EmailSender implements MessageSender {
    @Override
    public void sendMessage(String message) {
        System.out.println("Sending email: " + message);
    }
}

class SmsSender implements MessageSender {
    @Override
    public void sendMessage(String message) {
        System.out.println("Sending SMS: " + message);
    }
}

// Abstraction
abstract class Message {
    protected MessageSender sender;

    Message(MessageSender sender) {
        this.sender = sender;
    }

    abstract void send(String message);
}

// Refined Abstractions
class UrgentMessage extends Message {
    UrgentMessage(MessageSender sender) {
        super(sender);
    }

    @Override
    void send(String message) {
        sender.sendMessage("URGENT: " + message);
    }
}

class NormalMessage extends Message {
    NormalMessage(MessageSender sender) {
        super(sender);
    }

    @Override
    void send(String message) {
        sender.sendMessage(message);
    }
}

// Client code
public class BridgePatternDemo {
    public static void main(String[] args) {
        MessageSender emailSender = new EmailSender();
        MessageSender smsSender = new SmsSender();

        Message urgentEmail = new UrgentMessage(emailSender);
        urgentEmail.send("Meeting at 2 PM");

        Message normalSms = new NormalMessage(smsSender);
        normalSms.send("Reminder: Grocery shopping");
    }
}
```

组合模式

为客户端屏蔽对象和组合对象的具体实现提供统一的处理接口。

```jsx
// 抽象组件
public abstract class TreeNode {
    protected Long id;
    protected Long parentId;
    protected String name;
    protected Integer level;
    protected Integer sort;
    
    // 子节点操作
    public abstract void add(TreeNode node);
    public abstract void remove(TreeNode node);
    public abstract List<TreeNode> getChildren();
    
    // 树形结构操作
    public abstract List<TreeNode> getPath();
    public abstract boolean isLeaf();
    public abstract int getDepth();
}

// 叶子节点
public class TreeLeaf extends TreeNode {
    @Override
    public void add(TreeNode node) {
        throw new UnsupportedOperationException("Leaf node cannot add child");
    }
    
    @Override
    public void remove(TreeNode node) {
        throw new UnsupportedOperationException("Leaf node cannot remove child");
    }
    
    @Override
    public List<TreeNode> getChildren() {
        return Collections.emptyList();
    }
    
    @Override
    public List<TreeNode> getPath() {
        return Collections.singletonList(this);
    }
    
    @Override
    public boolean isLeaf() {
        return true;
    }
    
    @Override
    public int getDepth() {
        return 0;
    }
}

// 分支节点
public class TreeBranch extends TreeNode {
    private List<TreeNode> children = new ArrayList<>();
    
    @Override
    public void add(TreeNode node) {
        children.add(node);
    }
    
    @Override
    public void remove(TreeNode node) {
        children.remove(node);
    }
    
    @Override
    public List<TreeNode> getChildren() {
        return Collections.unmodifiableList(children);
    }
    
    @Override
    public List<TreeNode> getPath() {
        List<TreeNode> path = new ArrayList<>();
        path.add(this);
        if (!children.isEmpty()) {
            path.addAll(children.get(0).getPath());
        }
        return path;
    }
    
    @Override
    public boolean isLeaf() {
        return children.isEmpty();
    }
    
    @Override
    public int getDepth() {
        if (children.isEmpty()) {
            return 0;
        }
        return 1 + children.stream()
                          .mapToInt(TreeNode::getDepth)
                          .max()
                          .orElse(0);
    }
}
```

装饰器模式

动态地为对象添加一些额外的职责。

```jsx
// 组件接口
public interface Coffee {
    double cost();
    String getDescription();
}

// 具体组件
public class SimpleCoffee implements Coffee {
    @Override
    public double cost() {
        return 2.0; // 基础咖啡价格
    }

    @Override
    public String getDescription() {
        return "Simple Coffee"; // 描述
    }
}

----------------------------------------------------------------

// 装饰器
public abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee; // 持有一个Coffee对象

    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }
}

// 具体装饰器:牛奶
public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public double cost() {
        return coffee.cost() + 0.5; // 加牛奶的额外费用
    }

    @Override
    public String getDescription() {
        return coffee.getDescription() + ", Milk"; // 添加描述
    }
}

// 具体装饰器:糖
public class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public double cost() {
        return coffee.cost() + 0.2; // 加糖的额外费用
    }

    @Override
    public String getDescription() {
        return coffee.getDescription() + ", Sugar"; // 添加描述
    }
}

---------------------------------------------------------------------------------------

public class CoffeeShop {
    public static void main(String[] args) {
        Coffee coffee = new SimpleCoffee(); // 创建基础咖啡
        System.out.println(coffee.getDescription() + " $" + coffee.cost());

        // 添加牛奶装饰
        coffee = new MilkDecorator(coffee);
        System.out.println(coffee.getDescription() + " $" + coffee.cost());

        // 添加糖装饰
        coffee = new SugarDecorator(coffee);
        System.out.println(coffee.getDescription() + " $" + coffee.cost());
    }
}
```

外观模式

封装子系统功能并提供简单的接口调用。

  • 计算机启动示例

    // 子系统类1
    public class CPU {
        public void freeze() {
            System.out.println("CPU is freezing.");
        }
    
        public void jump(long position) {
            System.out.println("CPU is jumping to: " + position);
        }
    
        public void execute() {
            System.out.println("CPU is executing.");
        }
    }
    
    // 子系统类2
    public class Memory {
        public void load(long position, byte[] data) {
            System.out.println("Memory is loading data at position: " + position);
        }
    }
    
    // 子系统类3
    public class HardDrive {
        public byte[] read(long lba, int size) {
            System.out.println("HardDrive is reading data from LBA: " + lba + ", size: " + size);
            return new byte[size]; // 返回模拟数据
        }
    }
    
    // 外观类
    public class ComputerFacade {
        private CPU cpu;
        private Memory memory;
        private HardDrive hardDrive;
    
        public ComputerFacade() {
            this.cpu = new CPU();
            this.memory = new Memory();
            this.hardDrive = new HardDrive();
        }
    
        public void startComputer() {
            cpu.freeze();
            memory.load(0, hardDrive.read(0, 1024));
            cpu.jump(0);
            cpu.execute();
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            ComputerFacade computer = new ComputerFacade();
            computer.startComputer(); // 启动计算机
        }
    }
    

享元模式

也称为: 缓存

通过构建映射实现对象重用。

```jsx
// 享元接口
public interface Shape {
    void draw(String color);
}

// 具体享元类
public class Circle implements Shape {
    private String type; // 内部状态

    public Circle() {
        this.type = "Circle"; // 共享的状态
    }

    @Override
    public void draw(String color) {
        System.out.println("Drawing a " + color + " " + type);
    }
}

// 享元工厂
import java.util.HashMap;
import java.util.Map;

public class ShapeFactory {
    private Map<String, Shape> shapes = new HashMap<>();

    public Shape getCircle(String color) {
        Shape circle = shapes.get(color);
        if (circle == null) {
            circle = new Circle();
            shapes.put(color, circle);
            System.out.println("Creating a new circle of color: " + color);
        }
        return circle;
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        ShapeFactory shapeFactory = new ShapeFactory();

        // 创建并使用享元对象
        Shape redCircle = shapeFactory.getCircle("Red");
        redCircle.draw("Red");

        Shape greenCircle = shapeFactory.getCircle("Green");
        greenCircle.draw("Green");

        // 共享相同的对象
        Shape anotherRedCircle = shapeFactory.getCircle("Red");
        anotherRedCircle.draw("Red");

        // 输出结果
        System.out.println("Red circle and another red circle are the same object: " + (redCircle == anotherRedCircle));
    }
}
```

代理模式

创建一个代理对象来控制对真实对象的调用,以实现额外的功能。

```jsx
// 主题接口
public interface Subject {
    void request();
}

// 真实对象
public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}

// 代理对象
public class Proxy implements Subject {
    private RealSubject realSubject;

    @Override
    public void request() {
        if (realSubject == null) {
            realSubject = new RealSubject(); // 延迟加载
        }
        // 代理的额外功能
        System.out.println("Proxy: Pre-processing request.");
        realSubject.request(); // 调用真实对象的方法
        System.out.println("Proxy: Post-processing request.");
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Subject subject = new Proxy(); // 使用代理对象
        subject.request(); // 通过代理对象调用请求
    }
}
```

代理模式与装饰器模式的区别:实现方式类似,但目标不同:
代理:专注于调用对象的控制。
装饰器:专注于功能扩展。

action test 001