【Java高级篇】——第13篇:深入探讨设计模式与Java实践

第13篇:深入探讨设计模式与Java实践

设计模式是解决软件设计中常见问题的经验总结,是构建可维护、可扩展代码的基石。本文将从 设计模式分类六大核心原则 出发,深入解析23种经典设计模式在Java中的实现,并结合Spring框架、JDK源码及实际场景,探讨模式的应用与演进。


1. 设计模式核心原则

原则 核心思想 典型应用场景
开闭原则 (OCP) 对扩展开放,对修改关闭 通过抽象层扩展功能(策略模式)
单一职责 (SRP) 一个类只负责一个功能领域 拆分臃肿类(状态模式)
里氏替换 (LSP) 子类必须能替换父类且不影响程序正确性 继承体系设计(模板方法模式)
接口隔离 (ISP) 客户端不应依赖它不需要的接口 拆分庞大接口(适配器模式)
依赖倒置 (DIP) 高层模块不依赖低层模块,两者依赖抽象 依赖注入(Spring IoC)
迪米特法则 (LoD) 减少对象间的耦合,只与直接朋友通信 门面模式封装子系统交互

2. 创建型模式:对象创建的艺术

2.1 工厂方法模式(Factory Method)

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

java 复制代码
// 抽象产品
interface Logger {
    void log(String message);
}

// 具体产品
class FileLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("File: " + message);
    }
}

// 抽象工厂
interface LoggerFactory {
    Logger createLogger();
}

// 具体工厂
class FileLoggerFactory implements LoggerFactory {
    @Override
    public Logger createLogger() {
        return new FileLogger();
    }
}

// 使用
LoggerFactory factory = new FileLoggerFactory();
Logger logger = factory.createLogger();
logger.log("Test message");

应用场景

  • JDK中的Calendar.getInstance()
  • Spring的BeanFactory
2.2 抽象工厂模式(Abstract Factory)

意图:创建相关或依赖对象的家族,而无需指定具体类。

java 复制代码
// 抽象产品族
interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

// 具体工厂(Windows风格)
class WinFactory implements GUIFactory {
    public Button createButton() { return new WinButton(); }
    public Checkbox createCheckbox() { return new WinCheckbox(); }
}

// 客户端代码
public class Application {
    private GUIFactory factory;
    
    public Application(GUIFactory factory) {
        this.factory = factory;
    }
    
    public void render() {
        Button btn = factory.createButton();
        btn.paint(); // 输出Windows风格按钮
    }
}

典型应用

  • Java Swing的LookAndFeel
  • 数据库连接工厂(MySQL/Oracle驱动)

3. 结构型模式:构建灵活架构

3.1 适配器模式(Adapter)

意图:转换接口使得不兼容的类可以协作。

java 复制代码
// 目标接口(客户端期望的接口)
interface MediaPlayer {
    void play(String audioType, String fileName);
}

// 被适配者(已有实现)
class Mp4Player {
    void playMp4(String fileName) {
        System.out.println("Playing MP4: " + fileName);
    }
}

// 适配器
class Mp4Adapter implements MediaPlayer {
    private Mp4Player mp4Player = new Mp4Player();

    @Override
    public void play(String audioType, String fileName) {
        if ("mp4".equalsIgnoreCase(audioType)) {
            mp4Player.playMp4(fileName);
        }
    }
}

// 使用
MediaPlayer player = new Mp4Adapter();
player.play("mp4", "movie.mp4");

JDK实例

  • Arrays.asList() 将数组适配为List
  • Spring MVC的HandlerAdapter
3.2 装饰器模式(Decorator)

意图:动态地为对象添加职责。

java 复制代码
// 组件接口
interface Coffee {
    double getCost();
    String getDescription();
}

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

// 装饰器基类
abstract class CoffeeDecorator implements Coffee {
    protected Coffee decoratedCoffee;
    
    public CoffeeDecorator(Coffee coffee) {
        this.decoratedCoffee = coffee;
    }
}

// 具体装饰器
class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }
    
    public double getCost() {
        return decoratedCoffee.getCost() + 0.5;
    }
    
    public String getDescription() {
        return decoratedCoffee.getDescription() + ", Milk";
    }
}

// 使用
Coffee coffee = new MilkDecorator(new SimpleCoffee());
System.out.println(coffee.getDescription()); // "Simple Coffee, Milk"

JDK应用

  • Java IO流体系(如BufferedReader装饰FileReader

4. 行为型模式:对象间的协作

4.1 策略模式(Strategy)

意图:定义算法族,封装每个算法,使它们可互换。

java 复制代码
// 策略接口
interface PaymentStrategy {
    void pay(double amount);
}

// 具体策略
class CreditCardPayment implements PaymentStrategy {
    public void pay(double amount) {
        System.out.println("Paid $" + amount + " via Credit Card");
    }
}

class PayPalPayment implements PaymentStrategy {
    public void pay(double amount) {
        System.out.println("Paid $" + amount + " via PayPal");
    }
}

// 上下文
class ShoppingCart {
    private PaymentStrategy strategy;
    
    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }
    
    public void checkout(double amount) {
        strategy.pay(amount);
    }
}

// 使用
ShoppingCart cart = new ShoppingCart();
cart.setPaymentStrategy(new PayPalPayment());
cart.checkout(100.0);

应用场景

  • Java的Comparator排序策略
  • Spring的ResourceLoader策略
4.2 观察者模式(Observer)

意图:定义对象间的一对多依赖,当一个对象状态改变时,自动通知依赖对象。

java 复制代码
// 主题接口
interface Subject {
    void registerObserver(Observer o);
    void removeObserver(Observer o);
    void notifyObservers();
}

// 具体主题
class WeatherStation implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private float temperature;
    
    public void setTemperature(float temp) {
        this.temperature = temp;
        notifyObservers();
    }
    
    public void registerObserver(Observer o) {
        observers.add(o);
    }
    
    public void notifyObservers() {
        observers.forEach(o -> o.update(temperature));
    }
}

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

// 具体观察者
class Display implements Observer {
    public void update(float temperature) {
        System.out.println("Current temp: " + temperature);
    }
}

// 使用
WeatherStation station = new WeatherStation();
station.registerObserver(new Display());
station.setTemperature(25.5f); // 触发通知

JDK实现

  • java.util.Observable(已过时,建议自定义实现)
  • Spring的事件发布机制ApplicationEventPublisher

5. 模式演进与框架实践

5.1 Spring框架中的模式应用
模式 Spring实现示例 作用
工厂模式 BeanFactory 管理Bean的创建
代理模式 AOP的动态代理(JDK/CGLIB) 实现事务管理、日志切面
模板方法 JdbcTemplate 封装JDBC流程
单例模式 Bean的默认作用域 保证容器中Bean唯一
5.2 Java Stream API中的模式
  • 建造者模式Stream.Builder构建复杂流
  • 策略模式 :通过Lambda传递不同行为(如filtermap
  • 迭代器模式Spliterator实现并行遍历

6. 反模式与最佳实践

6.1 常见误用场景
  • 单例模式滥用:导致测试困难、隐藏依赖关系
  • 过度使用继承:违反组合优于继承原则
  • 为模式而模式:增加不必要的复杂性
6.2 设计原则实践
java 复制代码
// 违反开闭原则的代码
class ReportGenerator {
    public void generate(String type) {
        if ("PDF".equals(type)) {
            // PDF生成逻辑
        } else if ("CSV".equals(type)) {
            // CSV生成逻辑
        }
        // 新增类型需修改代码
    }
}

// 改进:使用策略模式
interface ReportStrategy {
    void generate();
}

class PdfStrategy implements ReportStrategy { /* ... */ }
class CsvStrategy implements ReportStrategy { /* ... */ }

class ReportGenerator {
    private ReportStrategy strategy;
    
    public void setStrategy(ReportStrategy strategy) {
        this.strategy = strategy;
    }
    
    public void generate() {
        strategy.generate();
    }
}

7. 现代架构中的模式演进

7.1 响应式编程与观察者模式

Reactive Streams规范(Publisher/Subscriber)是观察者模式的扩展:

java 复制代码
Flux.interval(Duration.ofSeconds(1))
    .map(i -> "Event " + i)
    .subscribe(System.out::println); // 订阅者
7.2 函数式编程与策略模式

通过Lambda简化策略实现:

java 复制代码
List<Integer> numbers = Arrays.asList(3, 1, 4);
numbers.sort((a, b) -> b.compareTo(a)); // 降序策略

8. 总结与进阶指南

  1. 模式选择原则

    • 优先使用组合而非继承
    • 识别变化点,封装不稳定部分
    • 避免过度设计,保持代码简洁
  2. 学习路径建议

    • 精读《设计模式:可复用面向对象软件的基础》(GoF)
    • 分析JDK和主流框架源码中的模式应用
    • 通过重构实践应用模式(如替换条件语句为策略模式)
  3. 工具支持

    • IDE插件(如IntelliJ IDEA的Pattern Analysis)
    • 架构守护工具(ArchiUnit验证架构约束)

附:23种设计模式速查表

分类 模式名称 核心场景
创建型 单例、工厂方法、抽象工厂、建造者、原型 对象创建解耦
结构型 适配器、桥接、组合、装饰器、门面、享元、代理 类与对象的结构组织
行为型 责任链、命令、迭代器、中介者、备忘录、观察者、状态、策略、模板方法、访问者 对象间的职责分配与通信

掌握设计模式不仅是学习解决方案,更是培养面向对象设计思维的过程。通过模式语言与持续实践,开发者能够构建出高内聚、低耦合的优雅系统架构。

相关推荐
软件开发技术局36 分钟前
撕碎QT面具(8):对控件采用自动增加函数(转到槽)的方式,发现函数不能被调用的解决方案
开发语言·qt
周杰伦fans2 小时前
C#中修饰符
开发语言·c#
yngsqq2 小时前
c# —— StringBuilder 类
java·开发语言
赔罪2 小时前
Python 高级特性-切片
开发语言·python
星星点点洲3 小时前
【操作幂等和数据一致性】保障业务在MySQL和COS对象存储的一致
java·mysql
xiaolingting3 小时前
JVM层面的JAVA类和实例(Klass-OOP)
java·jvm·oop·klass·instanceklass·class对象
风口上的猪20153 小时前
thingboard告警信息格式美化
java·服务器·前端
子豪-中国机器人4 小时前
2月17日c语言框架
c语言·开发语言
夏天的阳光吖4 小时前
C++蓝桥杯基础篇(四)
开发语言·c++·蓝桥杯
专注API从业者4 小时前
分布式电商系统中的API网关架构设计
大数据·数据仓库·分布式·架构