
你有没有想过为什么有些数字会反复出现在完全不同的领域23这个数字在生物学中是染色体的对数在软件工程中是经典设计模式的数量在几何学中是欧几里得定义的数量甚至在宗教哲学中也有特殊含义。这仅仅是巧合还是背后有更深层的规律作为一名长期关注软件架构和系统设计的开发者我发现这些看似无关的23现象其实揭示了一个重要规律复杂系统的构建往往遵循相似的模块化原则。无论是生物遗传、软件设计还是数学体系当系统复杂度达到一定程度时都会自然演化出20-30个核心构建模块。今天我们不讨论神秘学而是从工程实践的角度深入分析这种23模块定律在软件设计中的具体体现。本文将重点解析GoF的23种设计模式如何成为构建复杂软件的DNA并给出在实际项目中应用这些模式的实用指南。1. 为什么23个设计模式能统治软件工程30年1994年Erich Gamma等四位作者GoF在《设计模式可复用面向对象软件的基础》中提出了23种设计模式。近30年过去尽管编程语言、框架、架构风格发生了翻天覆地的变化但这23个模式依然是软件设计的基石。根本原因在于这23个模式解决了面向对象设计中最本质的复杂度管理问题。它们不是随意列举的而是针对对象间关系的几种基本场景的完整覆盖创建型模式5个处理对象实例化过程的复杂度结构型模式7个处理类与对象组合的复杂度行为型模式11个处理对象间职责分配的复杂度这种分类方式与生物学中23对染色体承载遗传信息的功能惊人相似。染色体是生物体的基础构建模块而设计模式是软件系统的基础构建模块。两者都在20-30这个数量级上达到了一种平衡足够覆盖基本场景又不会过于复杂难以掌握。2. 设计模式与染色体模块化思维的跨领域验证为了更好地理解23这个数字的意义我们先看看其他领域中类似的模块化现象领域核心模块数量功能描述与软件设计的类比生物学23对染色体承载人类遗传信息设计模式承载软件构建知识几何学23个定义欧几里得《几何原本》的基础软件设计的基础概念定义质数理论23第一个非孪生质数质数分布中的关键节点设计模式在软件架构中的关键作用这种跨领域的一致性说明当系统复杂度达到某个阈值时20-30个核心模块往往是最优解。太少则无法覆盖所有场景太多则增加学习和使用成本。在软件工程中这23个模式形成了一个完整的知识体系。比如当你需要解耦对象创建过程时你会想到工厂模式当需要为子系统提供统一接口时会想到外观模式当需要定义算法家族时会想到策略模式。3. 环境准备现代Java开发中的模式实践在深入具体模式之前我们先搭建一个现代化的开发环境。与1994年GoF成书时相比现在的工具链和最佳实践已经有了很大变化。3.1 基础环境配置# 使用Maven创建项目 mvn archetype:generate -DgroupIdcom.example.designpatterns \ -DartifactIddesign-patterns-demo \ -DarchetypeArtifactIdmaven-archetype-quickstart \ -DinteractiveModefalse # 项目结构 src/ ├── main/ │ └── java/ │ └── com/ │ └── example/ │ └── designpatterns/ │ ├── creational/ # 创建型模式 │ ├── structural/ # 结构型模式 │ └── behavioral/ # 行为型模式 └── test/ └── java/3.2 依赖管理配置!-- pom.xml -- project modelVersion4.0.0/modelVersion groupIdcom.example.designpatterns/groupId artifactIddesign-patterns-demo/artifactId version1.0-SNAPSHOT/version properties maven.compiler.source11/maven.compiler.source maven.compiler.target11/maven.compiler.target junit.version5.8.2/junit.version /properties dependencies dependency groupIdorg.junit.jupiter/groupId artifactIdjunit-jupiter/artifactId version${junit.version}/version scopetest/scope /dependency /dependencies /project3.3 现代IDE配置要点与20年前相比现代IDE如IntelliJ IDEA已经内置了对设计模式的深度支持模式识别IDE能自动识别代码中的模式使用情况重构工具提供将代码重构为特定模式的重构选项代码模板内置常用模式的代码模板4. 创建型模式实战控制对象创建的复杂度创建型模式的核心价值在于将对象创建与使用分离从而提高系统的灵活性和可维护性。我们重点分析三个最常用的模式。4.1 工厂方法模式灵活的对象创建工厂方法模式解决了直接调用构造函数带来的耦合问题。在实际项目中当创建逻辑比较复杂或可能变化时这个模式特别有用。// 文件路径src/main/java/com/example/designpatterns/creational/factory/LoggerFactory.java public interface Logger { void log(String message); } public class FileLogger implements Logger { Override public void log(String message) { // 写入文件的实现 System.out.println(File Logger: message); } } public class ConsoleLogger implements Logger { Override public void log(String message) { System.out.println(Console Logger: message); } } // 工厂接口 public interface LoggerFactory { Logger createLogger(); } // 具体工厂实现 public class FileLoggerFactory implements LoggerFactory { Override public Logger createLogger() { // 这里可以包含复杂的初始化逻辑 return new FileLogger(); } } public class ConsoleLoggerFactory implements LoggerFactory { Override public Logger createLogger() { return new ConsoleLogger(); } } // 使用示例 public class Client { public static void main(String[] args) { LoggerFactory factory new FileLoggerFactory(); Logger logger factory.createLogger(); logger.log(这是一个测试消息); } }工厂模式的关键优势将对象创建代码集中管理便于维护支持开闭原则新增产品类型时不需要修改客户端代码可以隐藏复杂的创建逻辑如缓存、池化等4.2 单例模式全局唯一实例的陷阱与正确用法单例模式是最容易被误用的模式之一。很多人只记得保证一个类只有一个实例却忽略了其带来的测试困难和潜在的内存泄漏问题。// 文件路径src/main/java/com/example/designpatterns/creational/singleton/SafeSingleton.java public class SafeSingleton { // 使用 volatile 确保多线程环境下的可见性 private static volatile SafeSingleton instance; private SafeSingleton() { // 防止外部实例化 if (instance ! null) { throw new IllegalStateException(单例实例已存在); } } // 双重检查锁定实现线程安全 public static SafeSingleton getInstance() { if (instance null) { synchronized (SafeSingleton.class) { if (instance null) { instance new SafeSingleton(); } } } return instance; } // 业务方法 public void doSomething() { System.out.println(单例方法执行); } } // 更现代的实现枚举单例推荐 public enum EnumSingleton { INSTANCE; public void doSomething() { System.out.println(枚举单例方法执行); } } // 使用示例 public class SingletonClient { public static void main(String[] args) { // 传统单例使用 SafeSingleton singleton1 SafeSingleton.getInstance(); singleton1.doSomething(); // 枚举单例使用推荐 EnumSingleton.INSTANCE.doSomething(); } }单例模式使用注意事项优先考虑依赖注入而不是单例如果必须使用单例推荐枚举实现方式注意单例对象的生命周期管理避免内存泄漏单例模式会使单元测试变得困难需要额外考虑测试策略4.3 建造者模式复杂对象的逐步构建当对象的构造过程复杂且需要多种配置选项时建造者模式比重叠构造器或JavaBean模式更加优雅。// 文件路径src/main/java/com/example/designpatterns/creational/builder/Computer.java public class Computer { private final String cpu; // 必需参数 private final String ram; // 必需参数 private final String storage; // 必需参数 private final String graphicsCard; // 可选参数 private final String monitor; // 可选参数 private Computer(Builder builder) { this.cpu builder.cpu; this.ram builder.ram; this.storage builder.storage; this.graphicsCard builder.graphicsCard; this.monitor builder.monitor; } // 静态建造者类 public static class Builder { // 必需参数 private final String cpu; private final String ram; private final String storage; // 可选参数 - 使用默认值 private String graphicsCard 集成显卡; private String monitor 无显示器; public Builder(String cpu, String ram, String storage) { this.cpu cpu; this.ram ram; this.storage storage; } public Builder graphicsCard(String graphicsCard) { this.graphicsCard graphicsCard; return this; } public Builder monitor(String monitor) { this.monitor monitor; return this; } public Computer build() { return new Computer(this); } } // getter 方法 Override public String toString() { return String.format(Computer[CPU%s, RAM%s, Storage%s, Graphics%s, Monitor%s], cpu, ram, storage, graphicsCard, monitor); } } // 使用示例 public class BuilderClient { public static void main(String[] args) { Computer gamingComputer new Computer.Builder(Intel i9, 32GB, 1TB SSD) .graphicsCard(RTX 3080) .monitor(27寸4K) .build(); Computer officeComputer new Computer.Builder(Intel i5, 16GB, 512GB SSD) .build(); // 使用默认可选参数 System.out.println(游戏电脑: gamingComputer); System.out.println(办公电脑: officeComputer); } }建造者模式的优势构造过程清晰参数意义明确支持链式调用代码可读性强可以确保对象构造完成后的不可变性灵活处理可选参数避免构造器重载爆炸5. 结构型模式实战对象组合的艺术结构型模式关注如何组合类和对象形成更大的结构。它们主要处理两种关系类之间的继承关系和对象之间的组合关系。5.1 适配器模式解决接口不兼容问题适配器模式在系统集成、第三方库使用时特别有用。它就像电源插头转换器一样让不兼容的接口能够协同工作。// 文件路径src/main/java/com/example/designpatterns/structural/adapter/AdapterDemo.java // 目标接口我们系统期望的接口 interface MediaPlayer { void play(String audioType, String fileName); } // 被适配的类已有的实现但接口不兼容 class AdvancedMediaPlayer { public void playVlc(String fileName) { System.out.println(Playing vlc file: fileName); } public void playMp4(String fileName) { System.out.println(Playing mp4 file: fileName); } } // 适配器让AdvancedMediaPlayer适配MediaPlayer接口 class MediaAdapter implements MediaPlayer { private AdvancedMediaPlayer advancedMusicPlayer; public MediaAdapter(String audioType) { if (audioType.equalsIgnoreCase(vlc)) { advancedMusicPlayer new AdvancedMediaPlayer(); } else if (audioType.equalsIgnoreCase(mp4)) { advancedMusicPlayer new AdvancedMediaPlayer(); } } Override public void play(String audioType, String fileName) { if (audioType.equalsIgnoreCase(vlc)) { advancedMusicPlayer.playVlc(fileName); } else if (audioType.equalsIgnoreCase(mp4)) { advancedMusicPlayer.playMp4(fileName); } } } // 客户端代码使用适配器 public 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: fileName); } // 使用适配器支持其他格式 else if (audioType.equalsIgnoreCase(vlc) || audioType.equalsIgnoreCase(mp4)) { mediaAdapter new MediaAdapter(audioType); mediaAdapter.play(audioType, fileName); } else { System.out.println(Invalid media type: audioType); } } } // 使用示例 public class AdapterClient { public static void main(String[] args) { AudioPlayer audioPlayer new AudioPlayer(); audioPlayer.play(mp3, song.mp3); audioPlayer.play(mp4, movie.mp4); audioPlayer.play(vlc, video.vlc); audioPlayer.play(avi, video.avi); // 不支持的类型 } }5.2 装饰器模式动态扩展功能装饰器模式提供了比继承更灵活的功能扩展方式。它在Java I/O库中有经典应用。// 文件路径src/main/java/com/example/designpatterns/structural/decorator/DecoratorDemo.java // 组件接口 interface Coffee { double getCost(); String getDescription(); } // 具体组件 class SimpleCoffee implements Coffee { Override public double getCost() { return 1.0; } Override public String getDescription() { return 简单咖啡; } } // 装饰器抽象类 abstract class CoffeeDecorator implements Coffee { protected Coffee decoratedCoffee; public CoffeeDecorator(Coffee coffee) { this.decoratedCoffee coffee; } Override public double getCost() { return decoratedCoffee.getCost(); } Override public String getDescription() { return decoratedCoffee.getDescription(); } } // 具体装饰器 class MilkDecorator extends CoffeeDecorator { public MilkDecorator(Coffee coffee) { super(coffee); } Override public double getCost() { return super.getCost() 0.5; } Override public String getDescription() { return super.getDescription() , 加牛奶; } } class SugarDecorator extends CoffeeDecorator { public SugarDecorator(Coffee coffee) { super(coffee); } Override public double getCost() { return super.getCost() 0.2; } Override public String getDescription() { return super.getDescription() , 加糖; } } // 使用示例 public class DecoratorClient { public static void main(String[] args) { // 简单咖啡 Coffee coffee new SimpleCoffee(); System.out.println(coffee.getDescription() coffee.getCost()); // 加牛奶的咖啡 Coffee milkCoffee new MilkDecorator(new SimpleCoffee()); System.out.println(milkCoffee.getDescription() milkCoffee.getCost()); // 加牛奶和糖的咖啡 Coffee sweetMilkCoffee new SugarDecorator(new MilkDecorator(new SimpleCoffee())); System.out.println(sweetMilkCoffee.getDescription() sweetMilkCoffee.getCost()); } }6. 行为型模式实战对象间的交互与职责分配行为型模式主要关注对象之间的通信和职责分配。它们帮助对象更好地协作同时保持低耦合。6.1 策略模式算法的自由切换策略模式让算法可以独立于使用它的客户端变化这在需要支持多种业务规则或计算方式的场景中特别有用。// 文件路径src/main/java/com/example/designpatterns/behavioral/strategy/StrategyDemo.java // 策略接口 interface PaymentStrategy { void pay(int amount); } // 具体策略实现 class CreditCardStrategy implements PaymentStrategy { private String cardNumber; private String name; public CreditCardStrategy(String cardNumber, String name) { this.cardNumber cardNumber; this.name name; } Override public void pay(int amount) { System.out.println(amount 元使用信用卡支付卡号 cardNumber); } } class WeChatPayStrategy implements PaymentStrategy { private String wechatId; public WeChatPayStrategy(String wechatId) { this.wechatId wechatId; } Override public void pay(int amount) { System.out.println(amount 元使用微信支付微信号 wechatId); } } class AlipayStrategy implements PaymentStrategy { private String alipayAccount; public AlipayStrategy(String alipayAccount) { this.alipayAccount alipayAccount; } Override public void pay(int amount) { System.out.println(amount 元使用支付宝支付账号 alipayAccount); } } // 上下文类 class ShoppingCart { private ListString items new ArrayList(); private PaymentStrategy paymentStrategy; public void addItem(String item) { items.add(item); } public void setPaymentStrategy(PaymentStrategy strategy) { this.paymentStrategy strategy; } public void checkout(int amount) { if (paymentStrategy null) { throw new IllegalStateException(请先设置支付策略); } paymentStrategy.pay(amount); } } // 使用示例 public class StrategyClient { public static void main(String[] args) { ShoppingCart cart new ShoppingCart(); cart.addItem(商品1); cart.addItem(商品2); int totalAmount 200; // 使用信用卡支付 cart.setPaymentStrategy(new CreditCardStrategy(1234-5678-9012-3456, 张三)); cart.checkout(totalAmount); // 切换为微信支付 cart.setPaymentStrategy(new WeChatPayStrategy(wx_zhangsan)); cart.checkout(totalAmount); // 切换为支付宝支付 cart.setPaymentStrategy(new AlipayStrategy(zhangsanalipay.com)); cart.checkout(totalAmount); } }6.2 观察者模式对象间的消息通知观察者模式在事件驱动架构、GUI编程中广泛应用它建立了对象间的一对多依赖关系。// 文件路径src/main/java/com/example/designpatterns/behavioral/observer/ObserverDemo.java import java.util.ArrayList; import java.util.List; // 主题接口 interface Subject { void registerObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers(); } // 观察者接口 interface Observer { void update(String message); } // 具体主题天气预报系统 class WeatherStation implements Subject { private ListObserver observers new ArrayList(); private String weatherData; Override public void registerObserver(Observer observer) { observers.add(observer); } Override public void removeObserver(Observer observer) { observers.remove(observer); } Override public void notifyObservers() { for (Observer observer : observers) { observer.update(weatherData); } } public void setWeatherData(String weatherData) { this.weatherData weatherData; notifyObservers(); // 数据变化时通知所有观察者 } } // 具体观察者手机显示 class PhoneDisplay implements Observer { private String weatherInfo; Override public void update(String weatherData) { this.weatherInfo weatherData; display(); } public void display() { System.out.println(手机显示当前天气 - weatherInfo); } } // 具体观察者电视显示 class TVDisplay implements Observer { private String weatherInfo; Override public void update(String weatherData) { this.weatherInfo weatherData; display(); } public void display() { System.out.println(电视显示当前天气 - weatherInfo); } } // 使用示例 public class ObserverClient { public static void main(String[] args) { WeatherStation station new WeatherStation(); PhoneDisplay phone new PhoneDisplay(); TVDisplay tv new TVDisplay(); // 注册观察者 station.registerObserver(phone); station.registerObserver(tv); // 更新天气数据自动通知所有观察者 station.setWeatherData(晴天25°C); System.out.println( 天气变化 ); station.setWeatherData(多云22°C); // 移除一个观察者 station.removeObserver(tv); System.out.println( 移除电视显示后的变化 ); station.setWeatherData(小雨18°C); } }7. 设计模式在实际项目中的综合应用单独理解每个模式很重要但真正发挥价值的是在项目中组合使用多种模式。我们通过一个电商系统的订单处理模块来展示模式的实际组合应用。7.1 订单处理系统的模式组合// 文件路径src/main/java/com/example/designpatterns/realworld/OrderProcessingSystem.java // 订单类使用建造者模式 class Order { private final String orderId; private final String customerId; private final ListString items; private final double totalAmount; private final String status; private Order(Builder builder) { this.orderId builder.orderId; this.customerId builder.customerId; this.items builder.items; this.totalAmount builder.totalAmount; this.status builder.status; } public static class Builder { private final String orderId; private final String customerId; private ListString items new ArrayList(); private double totalAmount 0.0; private String status PENDING; public Builder(String orderId, String customerId) { this.orderId orderId; this.customerId customerId; } public Builder items(ListString items) { this.items items; return this; } public Builder totalAmount(double amount) { this.totalAmount amount; return this; } public Builder status(String status) { this.status status; return this; } public Order build() { return new Order(this); } } // getter方法 public String getOrderId() { return orderId; } public String getCustomerId() { return customerId; } public ListString getItems() { return items; } public double getTotalAmount() { return totalAmount; } public String getStatus() { return status; } } // 支付策略接口 interface PaymentStrategy { boolean processPayment(double amount, String orderId); } // 订单处理器使用模板方法模式 abstract class OrderProcessor { // 模板方法 public final void processOrder(Order order, PaymentStrategy paymentStrategy) { validateOrder(order); if (processPayment(order, paymentStrategy)) { updateInventory(order); notifyCustomer(order); logOrder(order); } else { handlePaymentFailure(order); } } protected abstract void validateOrder(Order order); protected abstract boolean processPayment(Order order, PaymentStrategy strategy); protected abstract void updateInventory(Order order); protected abstract void notifyCustomer(Order order); protected abstract void logOrder(Order order); protected abstract void handlePaymentFailure(Order order); } // 具体订单处理器 class StandardOrderProcessor extends OrderProcessor { Override protected void validateOrder(Order order) { System.out.println(验证订单: order.getOrderId()); } Override protected boolean processPayment(Order order, PaymentStrategy strategy) { System.out.println(处理支付金额: order.getTotalAmount()); return strategy.processPayment(order.getTotalAmount(), order.getOrderId()); } Override protected void updateInventory(Order order) { System.out.println(更新库存); } Override protected void notifyCustomer(Order order) { System.out.println(通知客户订单完成); } Override protected void logOrder(Order order) { System.out.println(记录订单日志); } Override protected void handlePaymentFailure(Order order) { System.out.println(处理支付失败); } } // 使用观察者模式处理订单事件 class OrderEventManager { private MapString, ListEventListener listeners new HashMap(); public OrderEventManager(String... operations) { for (String operation : operations) { listeners.put(operation, new ArrayList()); } } public void subscribe(String eventType, EventListener listener) { ListEventListener users listeners.get(eventType); users.add(listener); } public void unsubscribe(String eventType, EventListener listener) { ListEventListener users listeners.get(eventType); users.remove(listener); } public void notify(String eventType, String data) { ListEventListener users listeners.get(eventType); for (EventListener listener : users) { listener.update(data); } } } interface EventListener { void update(String data); } // 使用示例 public class OrderSystemDemo { public static void main(String[] args) { // 创建订单 Order order new Order.Builder(ORDER_001, CUST_123) .items(Arrays.asList(商品A, 商品B)) .totalAmount(199.99) .status(PROCESSING) .build(); // 设置支付策略 PaymentStrategy paymentStrategy new PaymentStrategy() { Override public boolean processPayment(double amount, String orderId) { System.out.println(模拟支付处理: 订单 orderId 金额 amount); return true; // 模拟支付成功 } }; // 处理订单 OrderProcessor processor new StandardOrderProcessor(); processor.processOrder(order, paymentStrategy); } }8. 设计模式常见误区与最佳实践在实际项目中使用设计模式时开发者容易陷入几个常见误区。了解这些陷阱能帮助你更好地运用模式。8.1 常见误区分析误区1过度设计问题在简单场景中使用复杂模式增加不必要的复杂度解决YAGNI原则You Aint Gonna Need It只在真正需要时引入模式误区2模式强迫症问题试图在代码中强行套用模式而不是让模式自然涌现解决先写可工作的代码再考虑重构为模式误区3忽视语言特性问题在支持函数式编程的语言中仍然使用传统的OOP模式解决了解现代语言特性如Java的Lambda、Stream API等8.2 最佳实践指南// 文件路径src/main/java/com/example/designpatterns/bestpractices/PatternBestPractices.java // 1. 优先使用组合而不是继承 class NotificationService { private MessageSender sender; private Logger logger; // 通过组合获得灵活性 public NotificationService(MessageSender sender, Logger logger) { this.sender sender; this.logger logger; } } // 2. 面向接口编程而不是具体实现 interface MessageSender { void send(String message); } class EmailSender implements MessageSender { Override public void send(String message) { System.out.println(发送邮件: message); } } class SMSSender implements MessageSender { Override public void send(String message) { System.out.println(发送短信: message); } } // 3. 使用依赖注入管理对象创建 class ServiceFactory { public static NotificationService createNotificationService() { MessageSender sender new EmailSender(); // 可配置 Logger logger new ConsoleLogger(); // 可配置 return new NotificationService(sender, logger); } } // 4. 保持类的单一职责 // 不好的做法一个类做太多事情 class BadOrderProcessor { public void processOrder() { /* 处理订单 */ } public void sendEmail() { /* 发送邮件 */ } public void updateInventory() { /* 更新库存 */ } public void generateReport() { /* 生成报告 */ } } // 好的做法职责分离 class OrderProcessor { public void processOrder() { /* 只处理订单逻辑 */ } } class EmailService { public void sendOrderConfirmation() { /* 专门处理邮件 */ } } class InventoryService { public void updateStock() { /* 专门处理库存 */ } }8.3 设计模式选择决策树当面临设计问题时可以按照以下流程选择合适的设计模式需要创建对象吗创建过程复杂→建造者模式需要控制实例数量→单例模式需要解耦创建逻辑→工厂模式需要组合对象或类吗接口不兼容→适配器模式需要动态添加功能→装饰器模式需要简化复杂接口→外观模式需要管理对象行为吗算法需要切换→策略模式对象状态变化需要通知→观察者模式需要封装请求→命令模式9. 设计模式的演进与现代化实践随着编程语言和开发范式的发展设计模式也在不断演进。了解这些变化能帮助你在现代项目中更好地应用模式。9.1 函数式编程对传统模式的影响在支持函数式编程的语言中很多模式可以用更简洁的方式实现// 文件路径src/main/java/com/example/designpatterns/modern/FunctionalPatterns.java import java.util.function.Function; import java.util.function.Predicate; // 传统策略模式 vs 函数式实现 class TraditionalStrategy { interface ValidationStrategy { boolean validate(String text); } class LengthValidator implements ValidationStrategy { Override public boolean validate(String text) { return text.length() 5; } } } // 函数式实现使用Predicate class FunctionalStrategy { public void validateText(String text, PredicateString validator) { if (validator.test(text)) { System.out.println(验证通过); } else { System.out.println(验证失败); } } public void demo() { // 使用Lambda表达式 validateText(hello, s - s.length() 5); validateText(test, s - s.contains(t)); } } // 传统观察者模式 vs 函数式实现 class FunctionalObserver { private ListConsumerString observers new ArrayList(); public void addObserver(ConsumerString observer) { observers.add(observer); } public void notifyObservers(String event) { observers.forEach(observer - observer.accept(event)); } }9.2 现代框架中的模式内化很多现代框架已经内置了设计模式的实现开发者不需要手动实现Spring框架依赖注入控制反转、单例模式、代理模式Java Stream API装饰器模式、策略模式Reactive编程观察者模式、迭代器模式9.3 设计模式与架构模式的关系理解设计模式与架构模式的区别很重要维度设计模式架构模式范围微观类/对象级别宏观系统级别关注点代码结构、对象关系系统分解、技术选型示例工厂模式、观察者模式MVC、微服务、事件驱动在实际项目中设计模式通常服务于架构模式。比如在微服务架构中你可能会使用工厂模式创建服务实例使用观察者模式处理服务间事件。10. 实战练习重构坏味道代码最好的学习方式是通过实际的重构练习。下面是一个典型的坏味道代码示例我们逐步将其重构为使用合适的设计模式。10.1 原始代码问题代码// 文件路径src/main/java/com/example/designpatterns/refactor/before/BadCode.java class OrderService { public void processOrder(String orderType, String customerType, double amount) { // 复杂的条件判断 if (orderType.equals(ONLINE)) { if (customerType.equals(VIP)) { // VIP在线订单处理逻辑 System.out.println(处理VIP在线订单); amount amount * 0.9; // 9折 } else if (customerType.equals(NORMAL)) { // 普通在线订单处理逻辑 System.out.println(处理普通在线订单); } } else if (orderType.equals(OFFLINE)) { if (customerType.equals(VIP)) { // VIP线下订单处理逻辑 System.out.println(处理VIP线下订单); amount amount * 0.8; // 8折 } else if (customerType.equals(NORMAL)) { // 普通线下订单处理逻辑 System.out.println(处理普通线下订单); } } // 支付处理 if (amount 1000) { // 大额支付逻辑 System.out.println(使用信用卡支付: amount); } else { // 小额支付逻辑 System.out.println(使用余额支付: amount); } // 通知逻辑 if (orderType.equals(ONLINE)) { System.out.println(发送邮件通知); } else { System.out.println(发送短信通知); } } }10.2 重构后的代码// 文件路径src/main/java/com/example/designpatterns/refactor/after/RefactoredCode.java // 使用策略模式处理折扣逻辑 interface DiscountStrategy { double applyDiscount(double originalAmount); } class VIPOnlineDiscount implements DiscountStrategy { Override public double applyDiscount(double originalAmount) { return originalAmount * 0.9; } } class VIPOfflineDiscount implements DiscountStrategy { Override public double applyDiscount(double originalAmount) { return originalAmount * 0.8; } } class NoDiscount implements DiscountStrategy { Override