🎭 Java设计模式详解:让代码优雅如诗的秘密武器

🎭 Java设计模式详解:让代码优雅如诗的秘密武器

💡 开篇小故事:小李是一名刚入行的程序员,他写的代码就像一团乱麻,每次修改都要花很长时间。直到有一天,他遇到了设计模式这位"代码魔法师"...

🎯 引言:为什么需要设计模式?

想象一下,如果你要建造一座房子:

  • 🏠 没有设计模式:就像用积木随意堆砌,看起来摇摇欲坠
  • 🏗️ 有设计模式:就像有专业的建筑图纸,每个房间都有明确的功能和位置

设计模式就是软件开发的"建筑图纸",让我们的代码从"乱糟糟的毛坯房"变成"精装修的豪宅"!

📊 设计模式能解决什么问题?

问题类型 没有设计模式 使用设计模式
代码重复 🔄 复制粘贴,改一处要改N处 ✨ 一次编写,多处复用
扩展困难 😰 添加新功能要改老代码 🚀 新功能独立添加
维护困难 😵 看不懂,不敢改 📖 清晰易懂,放心修改
测试困难 🧪 测试代码比业务代码还多 🎯 职责分离,测试简单

🎪 第一部分:设计模式基础 - 代码世界的"武林秘籍"

1.1 🎭 什么是设计模式?

定义:设计模式就像是编程界的"武林秘籍",是前辈们总结出来的解决特定问题的"招式"。

核心思想:不是教你写代码,而是教你"思考代码"的方式!

🎬 生活类比

  • 设计模式就像做菜的"菜谱"
  • 不同的菜谱解决不同的烹饪问题
  • 学会了菜谱,你就能做出各种美味佳肴

1.2 🏷️ 设计模式的分类 - 三大门派

📊 设计模式分类:GoF设计模式按职责分为三大类:

  • 🏭 创建型模式:负责对象的创建,就像工厂生产产品
  • 🏗️ 结构型模式:负责对象的结构和组合,就像建筑师设计房屋
  • 🎭 行为型模式:负责对象间的交互和通信,就像人与人之间的交流
🏆 GoF设计模式 - 软件开发的"圣经"

🎯 GoF是什么?

GoF"Gang of Four"(四人帮) 的缩写,指的是四位软件工程大师:

  • Erich Gamma - 瑞士苏黎世联邦理工学院教授
  • Richard Helm - IBM研究员
  • Ralph Johnson - 伊利诺伊大学香槟分校教授
  • John Vlissides - IBM研究员(已故)

这四位大师在1994年合作出版了《Design Patterns: Elements of Reusable Object-Oriented Software》(设计模式:可复用面向对象软件的基础),这本书被誉为软件开发的"圣经",首次系统性地提出了23种设计模式的概念和实现方法。

🏆 历史意义:GoF设计模式的出现,标志着软件工程从"手工艺时代"进入了"工程化时代",为后来的软件架构设计奠定了理论基础。

📋 设计模式完整清单(GoF 23种设计模式)

🎯 快速导航:以下是所有23种GoF设计模式的完整列表,你可以根据需要跳转到具体模式的学习。

🏭 创建型模式(5种)
序号 设计模式 英文全称 使用频率 难度等级
1 单例模式 Singleton Pattern ⭐⭐⭐⭐⭐ ⭐⭐
2 工厂方法模式 Factory Method Pattern ⭐⭐⭐⭐ ⭐⭐⭐
3 抽象工厂模式 Abstract Factory Pattern ⭐⭐⭐ ⭐⭐⭐⭐
4 建造者模式 Builder Pattern ⭐⭐⭐ ⭐⭐⭐
5 原型模式 Prototype Pattern ⭐⭐ ⭐⭐
🏗️ 结构型模式(7种)
序号 设计模式 英文全称 使用频率 难度等级
6 适配器模式 Adapter Pattern ⭐⭐⭐⭐ ⭐⭐
7 装饰器模式 Decorator Pattern ⭐⭐⭐⭐ ⭐⭐⭐
8 代理模式 Proxy Pattern ⭐⭐⭐⭐ ⭐⭐⭐
9 外观模式 Facade Pattern ⭐⭐⭐ ⭐⭐
10 桥接模式 Bridge Pattern ⭐⭐ ⭐⭐⭐⭐
11 组合模式 Composite Pattern ⭐⭐⭐ ⭐⭐⭐
12 享元模式 Flyweight Pattern ⭐⭐ ⭐⭐⭐⭐
🎭 行为型模式(11种)
序号 设计模式 英文全称 使用频率 难度等级
13 观察者模式 Observer Pattern ⭐⭐⭐⭐⭐ ⭐⭐
14 策略模式 Strategy Pattern ⭐⭐⭐⭐⭐ ⭐⭐
15 命令模式 Command Pattern ⭐⭐⭐ ⭐⭐⭐
16 状态模式 State Pattern ⭐⭐⭐ ⭐⭐⭐⭐
17 模板方法模式 Template Method Pattern ⭐⭐⭐⭐ ⭐⭐
18 迭代器模式 Iterator Pattern ⭐⭐⭐⭐ ⭐⭐
19 责任链模式 Chain of Responsibility Pattern ⭐⭐⭐ ⭐⭐⭐
20 中介者模式 Mediator Pattern ⭐⭐ ⭐⭐⭐⭐
21 访问者模式 Visitor Pattern ⭐⭐ ⭐⭐⭐⭐⭐
22 备忘录模式 Memento Pattern ⭐⭐ ⭐⭐⭐
23 解释器模式 Interpreter Pattern ⭐⭐⭐⭐⭐

💡 使用频率说明

  • ⭐⭐⭐⭐⭐:非常常用,必须掌握

  • ⭐⭐⭐⭐:常用,建议掌握

  • ⭐⭐⭐:中等使用频率

  • ⭐⭐:较少使用

  • ⭐:很少使用,了解即可
    🎯 难度等级说明

  • ⭐⭐:简单,容易理解

  • ⭐⭐⭐:中等,需要一定理解

  • ⭐⭐⭐⭐:较难,需要深入理解

  • ⭐⭐⭐⭐⭐:很难,需要大量实践

1.3 💎 设计模式的价值 - 从"菜鸟"到"大神"的蜕变

🚫 没有设计模式 - "菜鸟代码"
csharp 复制代码
// 😰 菜鸟小李的代码 - 硬编码,难以维护
public class PaymentService {
    public void processPayment(String paymentType, double amount) {
        if (paymentType.equals("alipay")) {
            System.out.println("使用支付宝支付: " + amount);
        } else if (paymentType.equals("wechat")) {
            System.out.println("使用微信支付: " + amount);
        } else if (paymentType.equals("bank")) {
            System.out.println("使用银行卡支付: " + amount);
        }
        // 😱 如果要添加新的支付方式,又要改这里!
    }
}
✨ 使用设计模式 - "大神代码"
java 复制代码
// 🎯 大神小红的代码 - 策略模式,优雅扩展
public interface PaymentStrategy {
    void pay(double amount);
}

public class AlipayStrategy implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("使用支付宝支付: " + amount);
    }
}

public class WechatStrategy implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("使用微信支付: " + amount);
    }
}

public class PaymentService {
    private PaymentStrategy strategy;
    
    public void setStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }
    
    public void processPayment(double amount) {
        strategy.pay(amount);
    }
}

// 🚀 添加新支付方式,只需要实现新策略,不需要修改现有代码!
public class BitcoinStrategy implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("使用比特币支付: " + amount);
    }
}

1.4 🌟 设计模式的应用场景 - 真实世界的"魔法"

🏢 框架开发中的设计模式
框架 使用的设计模式 作用
Spring 🏭 工厂模式、🎭 代理模式 管理Bean、AOP切面
MyBatis 🏗️ 建造者模式、🎭 代理模式 构建SQL、动态代理
JDK 🎯 单例模式、🎭 策略模式 工具类、集合框架
💼 业务开发中的设计模式
业务场景 推荐设计模式 解决的问题
支付系统 🎭 策略模式 多种支付方式
日志系统 👀 观察者模式 事件通知
缓存系统 🎨 装饰器模式 功能增强

1.5 📚 学习建议 - 从小白到大神的修炼之路

  1. 🎯 理解原理:不要死记硬背,要理解每个模式解决的问题
  2. 🛠️ 实践应用:在实际项目中尝试使用设计模式
  3. ⚖️ 避免过度设计:不是所有地方都需要使用设计模式
  4. 🎭 结合场景:根据具体场景选择合适的设计模式

🎪 第二部分:SOLID原则详解 - 代码世界的"武林心法"

💡 小故事继续:小李学会了设计模式后,代码质量提升了很多。但是他的师父告诉他:"徒儿,光有招式还不够,你还需要修炼心法!"
📚 SOLID原则创始人 :SOLID原则是由 Robert C. Martin(也被称为"Uncle Bob")在2000年提出的面向对象设计的五个基本原则。这些原则是面向对象编程和设计的基石。
📊 SOLID原则概览

🎯 原则 📖 英文全称 🇨🇳 中文名称 💡 核心思想
S Single Responsibility Principle 单一职责原则 一个类只做一件事
O Open-Closed Principle 开闭原则 对扩展开放,对修改关闭
L Liskov Substitution Principle 里氏替换原则 子类可以替换父类
I Interface Segregation Principle 接口隔离原则 使用多个专门接口
D Dependency Inversion Principle 依赖倒置原则 依赖抽象而非具体

2.1 🎯 单一职责原则(SRP)- "一心一意"

2.1.1 定义与理解

定义:一个类应该只有一个引起它变化的原因。

核心思想:就像一个人,最好只专注做一件事,并且把它做好!

🎭 生活类比

  • 厨师只负责做菜
  • 服务员只负责服务
  • 收银员只负责收钱
  • 如果一个人又要做菜又要收钱,就容易出错
2.1.2 🚫 违反SRP的示例 - "全能超人"
typescript 复制代码
// 😰 违反SRP的类 - 一个类承担了太多职责
public class UserManager {
    // 用户管理职责
    public void createUser(User user) {
        // 创建用户逻辑
    }
    
    public void updateUser(User user) {
        // 更新用户逻辑
    }
    
    public void deleteUser(Long userId) {
        // 删除用户逻辑
    }
    
    // 数据持久化职责
    public void saveToDatabase(User user) {
        // 数据库操作逻辑
    }
    
    public void loadFromDatabase(Long userId) {
        // 数据库查询逻辑
    }
    
    // 日志记录职责
    public void logUserAction(String action, User user) {
        // 日志记录逻辑
    }
    
    // 邮件发送职责
    public void sendWelcomeEmail(User user) {
        // 邮件发送逻辑
    }
    
    // 😱 这个类承担了太多职责,违反了SRP!
}
2.1.3 ✨ 遵循SRP的重构 - "专业分工"
typescript 复制代码
// 🎯 用户服务类 - 只负责用户业务逻辑
public class UserService {
    private UserRepository userRepository;
    private EmailService emailService;
    private LogService logService;
    
    public UserService(UserRepository userRepository, 
                      EmailService emailService, 
                      LogService logService) {
        this.userRepository = userRepository;
        this.emailService = emailService;
        this.logService = logService;
    }
    
    public void createUser(User user) {
        userRepository.save(user);
        emailService.sendWelcomeEmail(user);
        logService.logUserAction("CREATE", user);
    }
    
    public void updateUser(User user) {
        userRepository.update(user);
        logService.logUserAction("UPDATE", user);
    }
    
    public void deleteUser(Long userId) {
        userRepository.delete(userId);
        logService.logUserAction("DELETE", userId);
    }
}

// 🗄️ 数据持久化类 - 只负责数据访问
public class UserRepository {
    private DatabaseConnection dbConnection;
    
    public void save(User user) {
        // 数据库保存逻辑
    }
    
    public void update(User user) {
        // 数据库更新逻辑
    }
    
    public void delete(Long userId) {
        // 数据库删除逻辑
    }
    
    public User findById(Long userId) {
        // 数据库查询逻辑
        return null;
    }
}

// 📧 邮件服务类 - 只负责邮件发送
public class EmailService {
    public void sendWelcomeEmail(User user) {
        // 邮件发送逻辑
    }
    
    public void sendPasswordResetEmail(User user) {
        // 密码重置邮件逻辑
    }
}

// 📝 日志服务类 - 只负责日志记录
public class LogService {
    public void logUserAction(String action, Object data) {
        // 日志记录逻辑
    }
}

2.2 🔓 开闭原则(OCP)- "开放扩展,关闭修改"

2.2.1 定义与理解

定义:软件实体应该对扩展开放,对修改关闭。

核心思想:当需要添加新功能时,应该通过添加新的代码来实现,而不是修改现有的代码。

🎭 生活类比

  • 就像乐高积木,你可以添加新的积木块,但不需要修改现有的积木
  • 就像手机APP,可以安装新应用,但不需要修改系统
2.2.2 🚫 违反OCP的示例 - "硬编码噩梦"
scss 复制代码
// 😰 违反OCP的代码 - 需要修改现有代码来支持新功能
public class ShapeCalculator {
    public double calculateArea(Object shape) {
        if (shape instanceof Circle) {
            Circle circle = (Circle) shape;
            return Math.PI * circle.getRadius() * circle.getRadius();
        } else if (shape instanceof Rectangle) {
            Rectangle rectangle = (Rectangle) shape;
            return rectangle.getWidth() * rectangle.getHeight();
        } else if (shape instanceof Triangle) {
            Triangle triangle = (Triangle) shape;
            return 0.5 * triangle.getBase() * triangle.getHeight();
        }
        return 0;
    }
}
2.2.3 ✨ 遵循OCP的重构 - "优雅扩展"
arduino 复制代码
// 🎯 遵循OCP的设计 - 通过接口实现扩展
public interface Shape {
    double calculateArea();
}

public class Circle implements Shape {
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
}

public class Rectangle implements Shape {
    private double width;
    private double height;
    
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double calculateArea() {
        return width * height;
    }
}

public class Triangle implements Shape {
    private double base;
    private double height;
    
    public Triangle(double base, double height) {
        this.base = base;
        this.height = height;
    }
    
    @Override
    public double calculateArea() {
        return 0.5 * base * height;
    }
}

// 🚀 计算器类不需要修改就能支持新形状
public class ShapeCalculator {
    public double calculateArea(Shape shape) {
        return shape.calculateArea();
    }
    
    public double calculateTotalArea(List<Shape> shapes) {
        return shapes.stream()
                    .mapToDouble(Shape::calculateArea)
                    .sum();
    }
}

// 🎉 添加新形状,只需要实现接口,不需要修改现有代码!
public class Hexagon implements Shape {
    private double side;
    
    public Hexagon(double side) {
        this.side = side;
    }
    
    @Override
    public double calculateArea() {
        return 3 * Math.sqrt(3) * side * side / 2;
    }
}

2.3 🔄 里氏替换原则(LSP)- "子承父业"

2.3.1 定义与理解

定义:子类对象应该能够替换其父类对象,而程序的行为不会发生改变。

核心思想:继承必须确保超类所拥有的性质在子类中仍然成立。

🎭 生活类比

  • 就像电器插座,只要是标准接口,任何品牌的电器都能插上使用
  • 就像USB接口,任何USB设备都能在USB接口上工作
2.3.2 🚫 违反LSP的示例 - "继承陷阱"
arduino 复制代码
// 😰 违反LSP的继承关系
public class Rectangle {
    protected double width;
    protected double height;
    
    public void setWidth(double width) {
        this.width = width;
    }
    
    public void setHeight(double height) {
        this.height = height;
    }
    
    public double getWidth() { return width; }
    public double getHeight() { return height; }
    
    public double calculateArea() {
        return width * height;
    }
}

// 正方形继承矩形 - 违反LSP
public class Square extends Rectangle {
    @Override
    public void setWidth(double width) {
        this.width = width;
        this.height = width; // 正方形宽高相等
    }
    
    @Override
    public void setHeight(double height) {
        this.width = height; // 正方形宽高相等
        this.height = height;
    }
}

// 🧪 测试代码 - 会出现问题
public class LSPViolationDemo {
    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle();
        rectangle.setWidth(5);
        rectangle.setHeight(4);
        System.out.println("矩形面积: " + rectangle.calculateArea()); // 20
        
        // 用正方形替换矩形
        Rectangle square = new Square();
        square.setWidth(5);
        square.setHeight(4);
        System.out.println("正方形面积: " + square.calculateArea()); // 16,行为改变了!
    }
}
2.3.3 ✨ 遵循LSP的重构 - "接口分离"
arduino 复制代码
// 🎯 遵循LSP的设计 - 使用组合而不是继承
public interface Shape {
    double calculateArea();
}

public class Rectangle implements Shape {
    private double width;
    private double height;
    
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    
    public void setWidth(double width) {
        this.width = width;
    }
    
    public void setHeight(double height) {
        this.height = height;
    }
    
    @Override
    public double calculateArea() {
        return width * height;
    }
}

public class Square implements Shape {
    private double side;
    
    public Square(double side) {
        this.side = side;
    }
    
    public void setSide(double side) {
        this.side = side;
    }
    
    @Override
    public double calculateArea() {
        return side * side;
    }
}

// 🧪 测试代码 - 行为一致
public class LSPComplianceDemo {
    public static void main(String[] args) {
        List<Shape> shapes = Arrays.asList(
            new Rectangle(5, 4),
            new Square(5)
        );
        
        for (Shape shape : shapes) {
            System.out.println("面积: " + shape.calculateArea());
        }
    }
}

2.4 🎭 接口隔离原则(ISP)- "小而美"

2.4.1 定义与理解

定义:客户端不应该依赖它不需要的接口。一个类对另一个类的依赖应该建立在最小的接口上。

核心思想:使用多个专门的接口比使用单个总接口要好。

🎭 生活类比

  • 就像瑞士军刀,虽然功能多,但每个功能都不够专业
  • 就像专业工具,每个工具都有专门的用途,用起来更顺手
2.4.2 🚫 违反ISP的示例 - "胖接口"
csharp 复制代码
// 😰 违反ISP的胖接口
public interface Worker {
    void work();
    void eat();
    void sleep();
    void getSalary();
    void takeVacation();
    void attendMeeting();
    void writeCode();
    void designArchitecture();
    void manageTeam();
}

// 程序员被迫实现不需要的方法
public class Programmer implements Worker {
    @Override
    public void work() {
        System.out.println("编程工作");
    }
    
    @Override
    public void eat() {
        System.out.println("吃饭");
    }
    
    @Override
    public void sleep() {
        System.out.println("睡觉");
    }
    
    @Override
    public void getSalary() {
        System.out.println("领取工资");
    }
    
    @Override
    public void takeVacation() {
        System.out.println("休假");
    }
    
    @Override
    public void attendMeeting() {
        System.out.println("参加会议");
    }
    
    @Override
    public void writeCode() {
        System.out.println("写代码");
    }
    
    @Override
    public void designArchitecture() {
        throw new UnsupportedOperationException("程序员不负责架构设计");
    }
    
    @Override
    public void manageTeam() {
        throw new UnsupportedOperationException("程序员不负责团队管理");
    }
}
2.4.3 ✨ 遵循ISP的重构 - "接口分离"
csharp 复制代码
// 🎯 遵循ISP的接口设计 - 接口分离
public interface Workable {
    void work();
}

public interface Eatable {
    void eat();
}

public interface Sleepable {
    void sleep();
}

public interface Payable {
    void getSalary();
}

public interface Vacationable {
    void takeVacation();
}

public interface MeetingAttendable {
    void attendMeeting();
}

public interface CodeWritable {
    void writeCode();
}

public interface ArchitectureDesignable {
    void designArchitecture();
}

public interface TeamManageable {
    void manageTeam();
}

// 程序员只需要实现相关的接口
public class Programmer implements Workable, Eatable, Sleepable, 
                                   Payable, Vacationable, MeetingAttendable, 
                                   CodeWritable {
    @Override
    public void work() {
        System.out.println("编程工作");
    }
    
    @Override
    public void eat() {
        System.out.println("吃饭");
    }
    
    @Override
    public void sleep() {
        System.out.println("睡觉");
    }
    
    @Override
    public void getSalary() {
        System.out.println("领取工资");
    }
    
    @Override
    public void takeVacation() {
        System.out.println("休假");
    }
    
    @Override
    public void attendMeeting() {
        System.out.println("参加会议");
    }
    
    @Override
    public void writeCode() {
        System.out.println("写代码");
    }
}

// 架构师实现更多接口
public class Architect implements Workable, Eatable, Sleepable, 
                                 Payable, Vacationable, MeetingAttendable, 
                                 CodeWritable, ArchitectureDesignable {
    // 实现所有方法...
}

// 项目经理实现管理相关接口
public class ProjectManager implements Workable, Eatable, Sleepable, 
                                     Payable, Vacationable, MeetingAttendable, 
                                     TeamManageable {
    // 实现相关方法...
}

2.5 🔄 依赖倒置原则(DIP)- "依赖抽象"

2.5.1 定义与理解

定义

  1. 高层模块不应该依赖低层模块,两者都应该依赖抽象。
  2. 抽象不应该依赖细节,细节应该依赖抽象。

核心思想:依赖抽象而不是具体实现。

🎭 生活类比

  • 就像电器插头,不依赖具体的插座品牌,只依赖标准接口
  • 就像USB设备,不依赖具体的电脑品牌,只依赖USB标准
2.5.2 🚫 违反DIP的示例 - "硬编码依赖"
csharp 复制代码
// 😰 违反DIP的代码 - 高层模块依赖低层模块
public class UserService {
    private MySQLDatabase database; // 直接依赖具体实现
    
    public UserService() {
        this.database = new MySQLDatabase(); // 硬编码依赖
    }
    
    public void createUser(User user) {
        database.save(user);
    }
    
    public User getUser(Long id) {
        return database.findById(id);
    }
}
2.5.3 ✨ 遵循DIP的重构 - "依赖抽象"
typescript 复制代码
// 🎯 遵循DIP的设计 - 依赖抽象
public interface UserRepository {
    void save(User user);
    User findById(Long id);
}

public class MySQLUserRepository implements UserRepository {
    @Override
    public void save(User user) {
        System.out.println("保存用户到MySQL数据库");
    }
    
    @Override
    public User findById(Long id) {
        System.out.println("从MySQL数据库查询用户");
        return new User();
    }
}

public class OracleUserRepository implements UserRepository {
    @Override
    public void save(User user) {
        System.out.println("保存用户到Oracle数据库");
    }
    
    @Override
    public User findById(Long id) {
        System.out.println("从Oracle数据库查询用户");
        return new User();
    }
}

// 高层模块依赖抽象
public class UserService {
    private UserRepository userRepository; // 依赖抽象
    
    public UserService(UserRepository userRepository) { // 依赖注入
        this.userRepository = userRepository;
    }
    
    public void createUser(User user) {
        userRepository.save(user);
    }
    
    public User getUser(Long id) {
        return userRepository.findById(id);
    }
}

// 🚀 使用示例 - 可以轻松切换不同的实现
public class DIPDemo {
    public static void main(String[] args) {
        UserRepository mysqlRepo = new MySQLUserRepository();
        UserService userService1 = new UserService(mysqlRepo);
        
        UserRepository oracleRepo = new OracleUserRepository();
        UserService userService2 = new UserService(oracleRepo);
    }
}

🎪 第三部分:SOLID原则的综合应用 - 真实项目实战

3.1 🛒 电商系统设计示例 - 从理论到实践

💡 场景设定:小李现在要开发一个电商系统,他要用SOLID原则来设计一个优雅的订单处理系统。

java 复制代码
// 🎯 遵循SOLID原则的电商系统设计
public interface OrderRepository {
    Order save(Order order);
    Order findById(Long id);
    List<Order> findByUserId(Long userId);
}

public interface PaymentProcessor {
    PaymentResult process(PaymentRequest request);
}

public interface InventoryManager {
    boolean reserveItems(List<OrderItem> items);
    void releaseItems(List<OrderItem> items);
}

public interface NotificationSender {
    void sendOrderConfirmation(Order order);
    void sendPaymentConfirmation(Order order);
}

// 🎯 订单服务 - 遵循SRP和DIP
@Service
public class OrderService {
    private final OrderRepository orderRepository;
    private final PaymentProcessor paymentProcessor;
    private final InventoryManager inventoryManager;
    private final NotificationSender notificationSender;
    
    public OrderService(OrderRepository orderRepository,
                       PaymentProcessor paymentProcessor,
                       InventoryManager inventoryManager,
                       NotificationSender notificationSender) {
        this.orderRepository = orderRepository;
        this.paymentProcessor = paymentProcessor;
        this.inventoryManager = inventoryManager;
        this.notificationSender = notificationSender;
    }
    
    public Order createOrder(OrderRequest request) {
        Order order = new Order(request);
        orderRepository.save(order);
        
        if (!inventoryManager.reserveItems(order.getItems())) {
            throw new InsufficientInventoryException();
        }
        
        PaymentRequest paymentRequest = new PaymentRequest(order);
        PaymentResult result = paymentProcessor.process(paymentRequest);
        
        if (result.isSuccess()) {
            order.setStatus(OrderStatus.PAID);
            orderRepository.save(order);
            notificationSender.sendOrderConfirmation(order);
            notificationSender.sendPaymentConfirmation(order);
        } else {
            inventoryManager.releaseItems(order.getItems());
            throw new PaymentFailedException(result.getErrorMessage());
        }
        
        return order;
    }
}

// 🗄️ 具体实现 - 遵循OCP和LSP
@Repository
public class JpaOrderRepository implements OrderRepository {
    private final OrderJpaRepository jpaRepository;
    
    public JpaOrderRepository(OrderJpaRepository jpaRepository) {
        this.jpaRepository = jpaRepository;
    }
    
    @Override
    public Order save(Order order) {
        return jpaRepository.save(order);
    }
    
    @Override
    public Order findById(Long id) {
        return jpaRepository.findById(id).orElse(null);
    }
    
    @Override
    public List<Order> findByUserId(Long userId) {
        return jpaRepository.findByUserId(userId);
    }
}

@Service
public class AlipayPaymentProcessor implements PaymentProcessor {
    @Override
    public PaymentResult process(PaymentRequest request) {
        // 支付宝支付逻辑
        return new PaymentResult(true, "支付成功");
    }
}

@Service
public class EmailNotificationSender implements NotificationSender {
    @Override
    public void sendOrderConfirmation(Order order) {
        // 发送订单确认邮件
    }
    
    @Override
    public void sendPaymentConfirmation(Order order) {
        // 发送支付确认邮件
    }
}

3.2 🎭 设计模式与SOLID原则的结合 - "招式"与"心法"的完美融合

typescript 复制代码
// 🎯 策略模式 + DIP - 折扣计算
public interface DiscountStrategy {
    double calculateDiscount(Order order);
}

public class VIPDiscountStrategy implements DiscountStrategy {
    @Override
    public double calculateDiscount(Order order) {
        return order.getTotalAmount() * 0.1; // VIP 10%折扣
    }
}

public class SeasonalDiscountStrategy implements DiscountStrategy {
    @Override
    public double calculateDiscount(Order order) {
        return order.getTotalAmount() * 0.05; // 季节性5%折扣
    }
}

// 🏭 工厂模式 + OCP - 支付处理器工厂
public interface PaymentProcessorFactory {
    PaymentProcessor createProcessor(String type);
}

public class PaymentProcessorFactoryImpl implements PaymentProcessorFactory {
    @Override
    public PaymentProcessor createProcessor(String type) {
        switch (type) {
            case "alipay":
                return new AlipayPaymentProcessor();
            case "wechat":
                return new WechatPaymentProcessor();
            case "bank":
                return new BankPaymentProcessor();
            default:
                throw new IllegalArgumentException("不支持的支付类型");
        }
    }
}

// 👀 观察者模式 + ISP - 订单事件监听
public interface OrderEventListener {
    void onOrderCreated(Order order);
    void onOrderPaid(Order order);
    void onOrderCancelled(Order order);
}

public class InventoryEventListener implements OrderEventListener {
    @Override
    public void onOrderCreated(Order order) {
        // 处理库存相关逻辑
    }
    
    @Override
    public void onOrderPaid(Order order) {
        // 处理库存相关逻辑
    }
    
    @Override
    public void onOrderCancelled(Order order) {
        // 处理库存相关逻辑
    }
}

public class NotificationEventListener implements OrderEventListener {
    @Override
    public void onOrderCreated(Order order) {
        // 发送通知
    }
    
    @Override
    public void onOrderPaid(Order order) {
        // 发送通知
    }
    
    @Override
    public void onOrderCancelled(Order order) {
        // 发送通知
    }
}

🎉 总结:从小白到大神的修炼之路

🏆 设计模式的价值:

  1. 🎯 提供解决方案:为常见设计问题提供标准化解决方案
  2. ✨ 提高代码质量:使代码更加清晰、可维护
  3. 🤝 促进团队协作:统一的语言和模式便于团队沟通
  4. ⚡ 提高开发效率:避免重复造轮子

🎯 SOLID原则的价值:

  1. 🔧 提高可维护性:清晰的代码结构,易于理解和修改
  2. 🚀 提高可扩展性:遵循开闭原则,易于添加新功能
  3. 🧪 提高可测试性:职责分离,便于单元测试
  4. 🎭 提高灵活性:依赖抽象而不是具体实现

📚 实践建议:

  1. 🧠 理解原理:不要死记硬背,要理解每个原则和模式的核心思想
  2. ⚖️ 适度使用:不是所有地方都需要使用设计模式,避免过度设计
  3. 🎭 结合场景:根据具体业务场景选择合适的设计模式
  4. 🔄 持续改进:在实际项目中不断实践和改进

🗺️ 学习路径建议 - 从小白到大神的修炼计划

🥉 初级阶段(入门)

目标 :理解基本概念,掌握常用模式 时间:2-3个月

必学设计模式 :单例模式、观察者模式、策略模式、工厂方法模式、装饰器模式 必学SOLID原则:单一职责原则(SRP)、开闭原则(OCP)

🥈 中级阶段(进阶)

目标 :深入理解,熟练应用 时间:3-6个月

进阶设计模式 :适配器模式、代理模式、模板方法模式、状态模式、抽象工厂模式 进阶SOLID原则:里氏替换原则(LSP)、接口隔离原则(ISP)、依赖倒置原则(DIP)

🥇 高级阶段(精通)

目标 :灵活运用,创新应用 时间:6-12个月

高级设计模式 :桥接模式、组合模式、命令模式、责任链模式、访问者模式 实战应用:框架开发、架构设计、重构实践

🏆 大师阶段(创新)

目标 :创造新的设计模式,指导他人 时间:持续学习

高级技能:模式组合、模式创新、知识传播、代码审查

📖 推荐学习资源

📚 经典书籍
  • 《设计模式:可复用面向对象软件的基础》- GoF四人帮著
  • 《Head First设计模式》- 通俗易懂的入门书
  • 《重构:改善既有代码的设计》- Martin Fowler著
  • 《代码整洁之道》- Robert C. Martin著
🌐 在线资源
🛠️ 实践工具

🎬 小李的成长故事结局:

💡 故事结尾:经过一段时间的学习和实践,小李的代码质量得到了显著提升。他的代码不再是"乱糟糟的毛坯房",而是变成了"精装修的豪宅"。同事们都说:"小李的代码写得真优雅!"小李笑着说:"这都是设计模式和SOLID原则的功劳!"


🎯 记住:设计模式和SOLID原则不是目的,而是手段。我们的目标是写出优雅、可维护、可扩展的代码。就像武林高手,招式是基础,心法是根本,两者结合才能成为真正的"代码大师"!

通过深入理解设计模式和SOLID原则,我们可以编写出更加优雅、可维护的代码,为项目的长期发展奠定良好的基础。让我们一起在编程的道路上不断修炼,成为真正的"代码艺术家"! 🎨✨

本文使用 markdown.com.cn 排版

相关推荐
永卿00110 分钟前
设计模式-责任链模式
java·设计模式·责任链模式
Codebee5 小时前
OneCode 3.0 智能数据处理:快速视图中的智能分页与 @PageBar 注解详解
后端·设计模式
Codebee5 小时前
OneCode 3.0智能分页拦截器深度解析:从拦截机制到性能优化
后端·设计模式
python_1366 小时前
python设计模式-工厂模式
开发语言·python·设计模式
k *6 小时前
c++:设计模式训练
设计模式
牛奶咖啡139 小时前
学习设计模式《二十》——解释器模式
学习·设计模式·解释器模式·认识解释器模式·解释器模式的优缺点·何时使用解释器模式·解释器模式的示例
北_鱼10 小时前
设计模式1:创建型模式
java·设计模式·软件工程·代码规范·设计规范
使一颗心免于哀伤10 小时前
《设计模式之禅》笔记摘录 - 12.适配器模式
笔记·设计模式
范纹杉想快点毕业11 小时前
基于 C 语言视角:流程图中分支与循环结构的深度解析
c语言·stm32·单片机·设计模式·架构·流程图·uml