【设计模式】设计模式简介与应用指南(2)

对设计模式的详细全面介绍,涵盖核心概念、23种经典设计模式、设计原则、应用场景及学习建议:


一、设计模式基础概念

1. 定义

设计模式(Design Pattern)是解决软件设计中常见问题的可复用方案,它是对代码设计经验的总结,提供了一套被验证的、可扩展的代码结构模板。

2. 核心价值

  • 代码复用:避免重复解决相同问题。
  • 解耦与扩展性:通过抽象和分层降低模块间依赖。
  • 提升可维护性:统一代码结构,便于团队理解和修改。
  • 优化性能:部分模式直接解决性能问题(如享元模式)。

3. 设计模式与架构模式的区别

  • 设计模式:微观层面的代码结构优化(如单个模块或类的关系)。
  • 架构模式:宏观层面的系统结构设计(如MVC、微服务、事件驱动)。

二、GoF 23种经典设计模式详解

根据《设计模式:可复用面向对象软件的基础》(GoF)分类:


(一)创建型模式(5种)

核心目标:解耦对象创建过程,增强灵活性和可控制性。

1. 工厂方法模式(Factory Method)
  • 问题:需创建多种类型对象,但不想在代码中硬编码具体类。
  • 实现:定义接口创建对象,由子类决定实例化哪个类。
  • 示例
    interface Shape { void draw(); }
    class Circle implements Shape { public void draw() { /*画圆*/ } }
    class ShapeFactory {
        public Shape createShape(String type) {
            if ("circle".equals(type)) return new Circle();
            // 其他形状...
        }
    }
    
2. 抽象工厂模式(Abstract Factory)
  • 问题:需要创建一组相关或依赖的对象(如不同主题的UI组件)。
  • 实现:提供接口创建多个产品族,而非单一产品。
  • 示例
    interface GUIFactory {
        Button createButton();
        Checkbox createCheckbox();
    }
    class WindowsFactory implements GUIFactory { /*返回Windows风格组件*/ }
    class MacFactory implements GUIFactory { /*返回Mac风格组件*/ }
    
3. 单例模式(Singleton)
  • 问题:确保全局唯一实例(如数据库连接池)。
  • 实现:私有构造函数 + 静态实例 + 全局访问点。
  • 注意:多线程需加锁(双重检查锁定)。
    public class Singleton {
        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;
        }
    }
    
4. 建造者模式(Builder)
  • 问题:构造复杂对象时避免构造函数参数爆炸。
  • 实现:分步构建,最后返回完整对象。
  • 示例:构建HTTP请求:
    Request request = new Request.Builder()
        .url("https://api.example.com")
        .method("POST")
        .header("Content-Type", "application/json")
        .body("{...}")
        .build();
    
5. 原型模式(Prototype)
  • 问题:需高效复制复杂对象(如游戏中的敌人克隆)。
  • 实现:实现Cloneable接口,重写clone()方法。
    class Enemy implements Cloneable {
        private String type;
        public Enemy clone() {
            return new Enemy(this.type); // 深拷贝需处理引用对象
        }
    }
    

(二)结构型模式(7种)

核心目标:通过组合类和对象形成更大的结构。

1. 适配器模式(Adapter)
  • 问题:让不兼容的接口协同工作(如旧系统升级)。
  • 实现
    • 类适配器:继承旧类实现新接口。
    • 对象适配器:持有旧类实例,实现新接口。
    // 旧类
    class LegacyPrinter {
        void printDocument() { /*...*/ }
    }
    // 适配器
    interface ModernPrinter {
        void print();
    }
    class PrinterAdapter implements ModernPrinter {
        private LegacyPrinter legacyPrinter;
        public void print() {
            legacyPrinter.printDocument();
        }
    }
    
2. 桥接模式(Bridge)
  • 问题:将抽象与实现解耦,使其独立变化(如不同图形API的绘制)。
  • 实现:分离抽象层(如形状)和实现层(如渲染引擎)。
    interface Renderer {
        void renderCircle(float radius);
    }
    class VectorRenderer implements Renderer { /*矢量渲染*/ }
    abstract class Shape {
        protected Renderer renderer;
        public Shape(Renderer r) { this.renderer = r; }
        abstract void draw();
    }
    class Circle extends Shape {
        private float radius;
        void draw() { renderer.renderCircle(radius); }
    }
    
3. 组合模式(Composite)
  • 问题:以树形结构处理部分-整体关系(如文件系统)。
  • 实现:统一叶子节点和组合节点的接口。
    interface FileSystemComponent {
        void display();
    }
    class File implements FileSystemComponent { /*文件*/ }
    class Directory implements FileSystemComponent {
        private List<FileSystemComponent> children = new ArrayList<>();
        void add(FileSystemComponent c) { children.add(c); }
        void display() { children.forEach(FileSystemComponent::display); }
    }
    
4. 装饰器模式(Decorator)
  • 问题:动态扩展对象功能(如Java I/O流)。
  • 实现:包装原有对象,新增职责。
    interface Coffee { double getCost(); }
    class SimpleCoffee implements Coffee { /*基础咖啡*/ }
    class MilkDecorator implements Coffee {
        private Coffee coffee;
        public MilkDecorator(Coffee c) { this.coffee = c; }
        public double getCost() { return coffee.getCost() + 0.5; }
    }
    
5. 外观模式(Facade)
  • 问题:简化复杂子系统的调用(如一键启动电脑)。
  • 实现:提供统一的高层接口。
    class Computer {
        private CPU cpu;
        private Memory memory;
        public void start() {
            cpu.initialize();
            memory.load();
            // 其他子系统操作...
        }
    }
    
6. 享元模式(Flyweight)
  • 问题:减少大量细粒度对象的内存消耗(如游戏中的树木)。
  • 实现:共享对象内部状态,区分外部状态。
    class TreeType {
        private String name, color;
        TreeType(String name, String color) { /*...*/ }
    }
    class TreeFactory {
        static Map<String, TreeType> pool = new HashMap<>();
        static TreeType getTreeType(String name, String color) {
            String key = name + "_" + color;
            if (!pool.containsKey(key)) {
                pool.put(key, new TreeType(name, color));
            }
            return pool.get(key);
        }
    }
    
7. 代理模式(Proxy)
  • 问题:控制对象访问(如延迟加载、权限校验)。
  • 实现:代理类持有真实对象引用,拦截请求。
    interface Image { void display(); }
    class RealImage implements Image { /*从磁盘加载大图*/ }
    class ProxyImage implements Image {
        private RealImage realImage;
        public void display() {
            if (realImage == null) realImage = new RealImage();
            realImage.display();
        }
    }
    

(三)行为型模式(11种)

核心目标:优化对象间的通信与责任分配。

1. 责任链模式(Chain of Responsibility)
  • 问题:多个对象依次处理请求(如审批流程)。
  • 实现:每个处理器决定是否处理或传递请求。
    abstract class Handler {
        protected Handler next;
        void setNext(Handler next) { this.next = next; }
        abstract void handleRequest(Request request);
    }
    class Manager extends Handler {
        void handleRequest(Request r) {
            if (canHandle(r)) { /*处理*/ } else { next.handleRequest(r); }
        }
    }
    
2. 命令模式(Command)
  • 问题:将请求封装为对象,支持撤销、队列等操作。
  • 实现:分离调用者与执行者。
    interface Command { void execute(); }
    class LightOnCommand implements Command {
        private Light light;
        public void execute() { light.on(); }
    }
    class RemoteControl {
        private Command command;
        public void pressButton() { command.execute(); }
    }
    
3. 解释器模式(Interpreter)
  • 问题:定义语言的文法规则(如SQL解析)。
  • 实现:构建语法树,递归解释表达式。
    interface Expression { boolean interpret(String context); }
    class TerminalExpression implements Expression {
        private String data;
        public boolean interpret(String context) {
            return context.contains(data);
        }
    }
    
4. 迭代器模式(Iterator)
  • 问题:统一遍历集合元素的方式。
  • 实现:分离集合结构与遍历逻辑。
    interface Iterator<T> {
        boolean hasNext();
        T next();
    }
    class ListIterator implements Iterator<String> {
        private List<String> list;
        private int index = 0;
        // 实现hasNext()和next()
    }
    
5. 中介者模式(Mediator)
  • 问题:减少对象间直接通信的复杂性(如聊天室)。
  • 实现:通过中介对象协调多个组件交互。
    class ChatRoom {
        public static void sendMessage(User user, String message) {
            // 处理消息分发逻辑
        }
    }
    
6. 备忘录模式(Memento)
  • 问题:捕获对象内部状态以实现撤销功能。
  • 实现:保存状态快照,由原发器管理。
    class Editor {
        private String content;
        public EditorMemento save() { return new EditorMemento(content); }
        public void restore(EditorMemento m) { content = m.getContent(); }
    }
    
7. 观察者模式(Observer)
  • 问题:实现一对多的依赖通知(如事件监听)。
  • 实现:主题维护观察者列表,状态变化时通知。
    interface Observer { void update(String message); }
    class User implements Observer {
        public void update(String msg) { System.out.println("收到消息: " + msg); }
    }
    class NewsPublisher {
        private List<Observer> observers = new ArrayList<>();
        public void addObserver(Observer o) { observers.add(o); }
        public void notify(String msg) { observers.forEach(o -> o.update(msg)); }
    }
    
8. 状态模式(State)
  • 问题:对象行为随状态改变(如订单状态流转)。
  • 实现:将状态抽象为独立类,委托行为给当前状态。
    interface OrderState {
        void next(Order order);
        void prev(Order order);
    }
    class PaidState implements OrderState {
        public void next(Order order) { order.setState(new ShippedState()); }
        // ...
    }
    
9. 策略模式(Strategy)
  • 问题:动态切换算法(如支付方式选择)。
  • 实现:定义算法族,封装每个算法。
    interface PaymentStrategy {
        void pay(int amount);
    }
    class CreditCardPayment implements PaymentStrategy { /*...*/ }
    class PayPalPayment implements PaymentStrategy { /*...*/ }
    class ShoppingCart {
        private PaymentStrategy strategy;
        public void checkout(int amount) { strategy.pay(amount); }
    }
    
10. 模板方法模式(Template Method)
  • 问题:定义算法骨架,允许子类重写某些步骤。
  • 实现:抽象类定义模板方法,子类实现具体步骤。
    abstract class Game {
        abstract void initialize();
        abstract void startPlay();
        // 模板方法
        public final void play() {
            initialize();
            startPlay();
            endPlay();
        }
    }
    
11. 访问者模式(Visitor)
  • 问题:在不修改类的前提下为类添加新操作(如代码分析工具)。
  • 实现:通过访问者对象处理不同元素。
    interface Visitor {
        void visit(ElementA element);
        void visit(ElementB element);
    }
    class ConcreteVisitor implements Visitor { /*实现各元素的处理方法*/ }
    

三、设计原则(SOLID)

设计模式的基础是面向对象设计原则:

  1. 单一职责原则(SRP):一个类只负责一个功能领域。
  2. 开闭原则(OCP):对扩展开放,对修改关闭。
  3. 里氏替换原则(LSP):子类必须能替换父类。
  4. 接口隔离原则(ISP):客户端不应依赖不需要的接口。
  5. 依赖倒置原则(DIP):依赖抽象而非具体实现。

四、设计模式的应用与陷阱

正确应用场景

  • 识别问题:明确代码痛点(如对象创建复杂、模块耦合度高)。
  • 选择模式:根据问题类型匹配模式(创建型/结构型/行为型)。
  • 适度使用:避免过度设计,简单代码优于复杂模式。

常见陷阱

  • 单例滥用:导致全局状态污染,难以测试。
  • 过度抽象:增加代码复杂度,降低可读性。
  • 模式误用:如用工厂模式创建简单对象。

五、学习路线与资源

学习路径

  1. 入门:理解设计原则(SOLID) → 学习常用模式(如工厂、观察者、策略)。
  2. 进阶:掌握23种GoF模式 → 分析框架源码(如Spring、JDK)。
  3. 实战:在项目中重构代码应用模式 → 总结优化经验。

推荐资源

  • 书籍
    • 《Head First设计模式》(入门首选)
    • 《设计模式:可复用面向对象软件的基础》(GoF经典)
    • 《重构:改善既有代码的设计》

设计模式是软件工程中的“内功心法”,深入理解并合理运用能显著提升代码质量。但切记:没有银弹,结合具体场景灵活选择才是王道。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晴雨日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值