文章目录
- 策略模式:在Java中实现灵活的行为选择
- 引言
- 1. 策略模式的组成
- 1.1 抽象策略 (Strategy)
- 1.2 具体策略 (Concrete Strategy)
- 1.3 上下文 (Context)
- 1.4 UML类图和时序图
- 2. 策略模式在Java中的实现
- 步骤一:定义抽象策略接口
- 步骤二:创建具体策略实现
- 步骤三:构建上下文
- 步骤四:使用策略模式
- 3. 策略模式的应用案例
- 案例一:排序算法的选择
- 案例二:支付方式的选择
- 案例三:优惠券计算
- 4. 策略模式的优缺点
- 5. 策略模式的设计原则
- 5.1 开闭原则
- 5.2 单一职责原则
- 5.3 里氏替换原则
- 6. 策略模式与相关模式对比
- 6.1 与工厂模式的比较
- 6.2 与状态模式的区别
- 6.3 与其他行为型模式的关系
- 7. 进阶主题
- 7.1 使用Java Lambda表达式简化策略模式
- 7.2 策略模式与依赖注入框架的结合
- 7.3 策略模式与Spring框架的集成
- 8. 常见问题解答
- 8.1 如何选择合适的策略?
- 8.2 如何处理策略之间的依赖关系?
- 9. 性能考量
- 9.1 性能影响分析
- 9.2 性能优化技巧
- 10. 最佳实践
- 10.1 何时使用策略模式
- 10.2 如何避免过度使用策略模式
- 10.3 避免常见陷阱
- 11. 总结
策略模式:在Java中实现灵活的行为选择
引言
1. 行为型模式简介
设计模式是一系列经过验证的解决方案,旨在解决软件开发过程中常见的问题。行为型模式是一种设计模式类别,它关注于封装系统中的算法和行为。这些模式通常涉及对象之间的交互方式,以及如何分配职责。通过使用行为型模式,开发者能够更好地组织代码并提高其可维护性。
2. 策略模式的意义
在软件工程中,策略模式是一种行为型设计模式,它使我们能够在运行时选择算法或行为。这种模式允许算法独立于使用它的客户端,并且可以轻松地替换不同的算法实现而不改变客户端代码。策略模式的主要优势在于它提高了代码的灵活性和可扩展性。
3. 策略模式的定义
定义与目的
策略模式定义了一个算法族,分别封装起来,让它们之间可以互相替换。此模式使得算法的变化不会影响到使用算法的客户。简单来说,策略模式允许我们在运行时更改算法或行为。
适用场景
- 当一个系统应该在其内部动态地选择从多个算法或行为中的一种时。
- 当一个算法的不同实现应当独立于使用该算法的客户时。
- 当一个算法需要提供多种变体时。
- 当控制在一个或多个特定的对象上执行算法比控制算法自身更重要时。
1. 策略模式的组成
1.1 抽象策略 (Strategy)
抽象策略定义了所有支持的算法的公共接口。这意味着客户端可以使用相同的接口来调用不同的算法实现。抽象策略通常是一个接口或抽象类,它声明了所有具体策略类都必须实现的方法。
示例代码:
public interface PaymentStrategy {void pay(int amount);
}
1.2 具体策略 (Concrete Strategy)
具体策略实现了抽象策略接口,并提供了实际的算法实现。每一个具体策略都代表了一种算法或行为。客户端可以通过配置不同的具体策略来决定使用哪种算法。
示例代码:
public class CreditCardStrategy implements PaymentStrategy {@Overridepublic void pay(int amount) {System.out.println(amount + " paid with credit/debit card");}
}public class PayPalStrategy implements PaymentStrategy {@Overridepublic void pay(int amount) {System.out.println(amount + " paid using PayPal.");}
}
1.3 上下文 (Context)
上下文定义了客户端如何使用策略。它维护一个对策略对象的引用,并且通常包含一个方法来设置这个引用。这样,客户端可以通过设置不同的策略对象来改变其行为。
示例代码:
public class ShoppingCart {private PaymentStrategy paymentStrategy;public ShoppingCart(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}public void setPaymentStrategy(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}public void checkout(int amount) {paymentStrategy.pay(amount);}
}
1.4 UML类图和时序图
2. 策略模式在Java中的实现
步骤一:定义抽象策略接口
首先,我们需要定义一个抽象策略接口,它将作为所有具体策略的公共接口。在这个例子中,我们将以一个简单的支付系统为例,其中支付策略是可选的,比如使用信用卡、PayPal等。
示例代码:
public interface PaymentStrategy {void pay(int amount);
}
步骤二:创建具体策略实现
接着,我们需要创建几个具体的策略实现类,这些类将实现上述定义的抽象策略接口。我们将创建两个具体的支付策略:CreditCardStrategy
和 PayPalStrategy
。
示例代码:
public class CreditCardStrategy implements PaymentStrategy {private String name;private String cardNumber;private String cvv;private String expiryDate;public CreditCardStrategy(String name, String cardNumber, String cvv, String expiryDate) {this.name = name;this.cardNumber = cardNumber;this.cvv = cvv;this.expiryDate = expiryDate;}@Overridepublic void pay(int amount) {System.out.println(amount + " paid with credit/debit card");}
}public class PayPalStrategy implements PaymentStrategy {private String emailId;private String password;public PayPalStrategy(String emailId, String password) {this.emailId = emailId;this.password = password;}@Overridepublic void pay(int amount) {System.out.println(amount + " paid using PayPal.");}
}
步骤三:构建上下文
现在我们需要创建一个上下文类,它将持有对策略对象的引用。上下文类将负责调用具体策略对象的方法。在我们的例子中,ShoppingCart
类将作为上下文。
示例代码:
public class ShoppingCart {private List<Item> items;private PaymentStrategy paymentStrategy;public ShoppingCart() {items = new ArrayList<>();}public void addItem(Item item) {items.add(item);}public void removeItem(Item item) {items.remove(item);}public int calculateTotal() {return items.stream().mapToInt(Item::getPrice).sum();}public void setPaymentStrategy(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}public void checkout() {int amount = calculateTotal();paymentStrategy.pay(amount);}
}class Item {private String name;private int price;public Item(String name, int price) {this.name = name;this.price = price;}public int getPrice() {return price;}
}
步骤四:使用策略模式
最后一步是编写客户端代码来演示如何使用策略模式。客户端将创建一个购物车实例,添加一些商品,然后选择一种支付策略进行结账。
客户端代码示例:
public class ShoppingCartClient {public static void main(String[] args) {// 创建购物车ShoppingCart cart = new ShoppingCart();// 添加商品cart.addItem(new Item("Apple", 10));cart.addItem(new Item("Banana", 20));// 设置支付策略PaymentStrategy strategy = new CreditCardStrategy("John Doe", "1234567890123456", "123", "12/25");cart.setPaymentStrategy(strategy);// 结账cart.checkout();// 更改支付策略strategy = new PayPalStrategy("john.doe@example.com", "mysecretpassword");cart.setPaymentStrategy(strategy);// 再次结账cart.checkout();}
}
这段代码展示了如何使用策略模式来实现支付功能。用户可以选择使用信用卡或PayPal支付,而购物车本身不需要关心具体的支付方式是如何实现的。这种方式使得系统更加灵活,易于扩展和维护。
3. 策略模式的应用案例
案例一:排序算法的选择
在这个案例中,我们将使用策略模式来实现不同的排序算法,如冒泡排序、快速排序等。这将允许我们在运行时选择最适合当前数据集的排序算法。
示例代码:
步骤一:定义抽象策略接口
public interface SortStrategy {void sort(int[] array);
}
步骤二:创建具体策略实现
public class BubbleSortStrategy implements SortStrategy {@Overridepublic void sort(int[] array) {boolean swapped;for (int i = 0; i < array.length - 1; i++) {swapped = false;for (int j = 0; j < array.length - 1 - i; j++) {if (array[j] > array[j + 1]) {int temp = array[j];array[j] = array[j + 1];array[j + 1] = temp;swapped = true;}}if (!swapped) break;}}
}public class QuickSortStrategy implements SortStrategy {public void sort(int[] array) {quickSort(array, 0, array.length - 1);}private void quickSort(int[] array, int low, int high) {if (low < high) {int pi = partition(array, low, high);quickSort(array, low, pi - 1);quickSort(array, pi + 1, high);}}private int partition(int[] array, int low, int high) {int pivot = array[high];int i = (low - 1);for (int j = low; j < high; j++) {if (array[j] <= pivot) {i++;int temp = array[i];array[i] = array[j];array[j] = temp;}}int temp = array[i + 1];array[i + 1] = array[high];array[high] = temp;return i + 1;}
}
步骤三:构建上下文
public class SortingContext {private SortStrategy sortStrategy;public SortingContext(SortStrategy sortStrategy) {this.sortStrategy = sortStrategy;}public void setSortStrategy(SortStrategy sortStrategy) {this.sortStrategy = sortStrategy;}public void sortArray(int[] array) {sortStrategy.sort(array);}
}
步骤四:使用策略模式
public class SortingClient {public static void main(String[] args) {int[] data = {10, 5, 8, 3, 7, 9, 1, 2};// 创建上下文SortingContext context = new SortingContext(new BubbleSortStrategy());// 排序context.sortArray(data);System.out.println("Sorted using Bubble Sort: " + Arrays.toString(data));// 更换策略context.setSortStrategy(new QuickSortStrategy());// 重新排序context.sortArray(data);System.out.println("Sorted using Quick Sort: " + Arrays.toString(data));}
}
案例二:支付方式的选择
我们已经在这个系列的前面部分介绍了支付方式的选择,这里再次简要回顾一下。
步骤一:定义抽象策略接口
public interface PaymentStrategy {void pay(int amount);
}
步骤二:创建具体策略实现
public class CreditCardStrategy implements PaymentStrategy {private String name;private String cardNumber;private String cvv;private String expiryDate;public CreditCardStrategy(String name, String cardNumber, String cvv, String expiryDate) {this.name = name;this.cardNumber = cardNumber;this.cvv = cvv;this.expiryDate = expiryDate;}@Overridepublic void pay(int amount) {System.out.println(amount + " paid with credit/debit card");}
}public class PayPalStrategy implements PaymentStrategy {private String emailId;private String password;public PayPalStrategy(String emailId, String password) {this.emailId = emailId;this.password = password;}@Overridepublic void pay(int amount) {System.out.println(amount + " paid using PayPal.");}
}
步骤三:构建上下文
public class ShoppingCart {private PaymentStrategy paymentStrategy;public ShoppingCart(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}public void setPaymentStrategy(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}public void checkout(int amount) {paymentStrategy.pay(amount);}
}
步骤四:使用策略模式
public class ShoppingCartClient {public static void main(String[] args) {ShoppingCart cart = new ShoppingCart(new CreditCardStrategy("John Doe", "1234567890123456", "123", "12/25"));cart.checkout(100);cart.setPaymentStrategy(new PayPalStrategy("john.doe@example.com", "password"));cart.checkout(100);}
}
案例三:优惠券计算
假设我们需要为一个电子商务平台实现一个优惠券系统,其中可以有不同的优惠券类型,例如百分比折扣、固定金额折扣等。我们将使用策略模式来实现这个系统。
步骤一:定义抽象策略接口
public interface DiscountStrategy {double applyDiscount(double totalAmount);
}
步骤二:创建具体策略实现
public class PercentageDiscountStrategy implements DiscountStrategy {private double percentage;public PercentageDiscountStrategy(double percentage) {this.percentage = percentage;}@Overridepublic double applyDiscount(double totalAmount) {return totalAmount * (1 - percentage / 100);}
}public class FixedAmountDiscountStrategy implements DiscountStrategy {private double amount;public FixedAmountDiscountStrategy(double amount) {this.amount = amount;}@Overridepublic double applyDiscount(double totalAmount) {return Math.max(totalAmount - amount, 0);}
}
步骤三:构建上下文
public class ShoppingCart {private DiscountStrategy discountStrategy;public ShoppingCart(DiscountStrategy discountStrategy) {this.discountStrategy = discountStrategy;}public void setDiscountStrategy(DiscountStrategy discountStrategy) {this.discountStrategy = discountStrategy;}public double calculateTotal(double totalAmount) {return discountStrategy.applyDiscount(totalAmount);}
}
步骤四:使用策略模式
public class ShoppingCartClient {public static void main(String[] args) {ShoppingCart cart = new ShoppingCart(new PercentageDiscountStrategy(10));double total = 1000.0;double discountedTotal = cart.calculateTotal(total);System.out.println("Total after 10% discount: " + discountedTotal);cart.setDiscountStrategy(new FixedAmountDiscountStrategy(50));discountedTotal = cart.calculateTotal(total);System.out.println("Total after $50 discount: " + discountedTotal);}
}
这些案例展示了策略模式在不同场景下的应用,可以帮助读者更好地理解如何在实际项目中使用策略模式。
4. 策略模式的优缺点
1. 优点
(1)易于扩展
- 策略模式允许我们在不修改现有代码的情况下增加新的策略。这意味着我们可以轻松地添加新的算法实现,而无需修改那些已经存在的代码。
(2)遵循开闭原则
- 根据开闭原则(Open-Closed Principle),软件实体应该是对扩展开放的,对修改关闭的。策略模式很好地遵循了这一原则,因为我们可以添加新的策略实现而不需要改变现有代码。
2. 缺点
(1)增加了对象数量
- 对于每一种策略,都需要创建一个新的类。这可能会导致类的数量增加,特别是在需要很多不同策略的情况下。
(2)客户端需要了解所有策略类
- 虽然策略模式允许客户端在运行时选择策略,但它也要求客户端知道所有可用的策略类。如果策略类太多,这可能会变得复杂。
5. 策略模式的设计原则
5.1 开闭原则
1. 定义
- 开闭原则指出,软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着我们可以轻松地添加新功能,而无需修改现有的代码。
2. 应用
- 在策略模式中,我们可以添加新的策略实现而不需要修改现有的策略接口或上下文类。这种特性使得系统更加灵活,易于维护。
5.2 单一职责原则
1. 定义
- 单一职责原则(Single Responsibility Principle)指出,一个类应该只有一个引起它变化的原因。这意味着一个类应该专注于完成一项任务。
2. 应用
- 在策略模式中,每个具体策略类只负责实现一个特定的算法或行为。这种分离使得代码更加清晰,每个类都有明确的目的。
5.3 里氏替换原则
1. 定义
- 里氏替换原则(Liskov Substitution Principle)指出,子类必须能够替换掉它们的父类,并且程序的行为不会因此发生变化。
2. 应用
- 在策略模式中,所有具体策略类都是抽象策略接口的子类。这意味着任何接受策略接口的地方都可以接受任何具体策略类的实例,而不会影响程序的行为。
6. 策略模式与相关模式对比
6.1 与工厂模式的比较
- 工厂模式:工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。工厂模式隐藏了对象创建的细节,并且允许系统独立于如何创建、组合或表示那些对象。
- 策略模式:策略模式是一种行为型设计模式,它允许在运行时更改算法或行为。
- 比较:工厂模式可以用来创建策略模式中的具体策略对象。例如,在策略模式中,我们可以使用工厂模式来创建具体的策略实例,而不是直接在客户端代码中实例化策略对象。这可以进一步降低客户端与具体策略实现之间的耦合度。
6.2 与状态模式的区别
- 状态模式:状态模式允许对象在其内部状态改变时改变其行为。状态模式允许一个对象看起来像是改变了它的类。
- 策略模式:策略模式允许在运行时更改算法或行为。它将一组相关的行为封装在一起,以便可以在运行时选择其中一个。
- 区别
- 状态模式适用于对象的行为随其内部状态改变的情况,而策略模式适用于对象的行为取决于外部输入或环境。
- 状态模式通常用于当对象的状态改变时,其行为也随之改变的情况。策略模式则用于在运行时根据需要选择不同的行为。
6.3 与其他行为型模式的关系
- 命令模式:命令模式将请求封装成对象,从而使你能够用不同的请求来参数化客户端,以及支持可撤销的操作。
- 观察者模式:观察者模式定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。
- 模板方法模式:模板方法模式定义了一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
- 关系:策略模式与其他行为型模式在设计上有所不同,但它们可以一起使用来实现更复杂的系统行为。例如,策略模式可以与观察者模式结合使用,以实现在不同策略下不同的行为变化通知机制。
7. 进阶主题
7.1 使用Java Lambda表达式简化策略模式
Java 8引入了Lambda表达式,这是一种简洁的方式来定义匿名函数。Lambda表达式可以用来简化策略模式的实现,尤其是当我们不需要创建单独的类来实现策略接口时。
示例代码:
步骤一:定义抽象策略接口
@FunctionalInterface
public interface SortStrategy {void sort(int[] array);
}
步骤二:创建具体策略实现
public class SortingClient {public static void main(String[] args) {int[] data = {10, 5, 8, 3, 7, 9, 1, 2};// 使用Lambda表达式定义策略SortStrategy bubbleSortStrategy = (array) -> {boolean swapped;for (int i = 0; i < array.length - 1; i++) {swapped = false;for (int j = 0; j < array.length - 1 - i; j++) {if (array[j] > array[j + 1]) {int temp = array[j];array[j] = array[j + 1];array[j + 1] = temp;swapped = true;}}if (!swapped) break;}};SortStrategy quickSortStrategy = (array) -> {quickSort(array, 0, array.length - 1);};// 使用策略SortingContext context = new SortingContext(bubbleSortStrategy);context.sortArray(data);System.out.println("Sorted using Bubble Sort: " + Arrays.toString(data));context.setSortStrategy(quickSortStrategy);context.sortArray(data);System.out.println("Sorted using Quick Sort: " + Arrays.toString(data));}private static void quickSort(int[] array, int low, int high) {if (low < high) {int pi = partition(array, low, high);quickSort(array, low, pi - 1);quickSort(array, pi + 1, high);}}private static int partition(int[] array, int low, int high) {int pivot = array[high];int i = (low - 1);for (int j = low; j < high; j++) {if (array[j] <= pivot) {i++;int temp = array[i];array[i] = array[j];array[j] = temp;}}int temp = array[i + 1];array[i + 1] = array[high];array[high] = temp;return i + 1;}
}
步骤三:构建上下文
public class SortingContext {private SortStrategy sortStrategy;public SortingContext(SortStrategy sortStrategy) {this.sortStrategy = sortStrategy;}public void setSortStrategy(SortStrategy sortStrategy) {this.sortStrategy = sortStrategy;}public void sortArray(int[] array) {sortStrategy.sort(array);}
}
7.2 策略模式与依赖注入框架的结合
依赖注入框架(如Spring)可以帮助管理策略模式中的依赖关系,从而减少代码耦合度。我们可以使用Spring框架来配置和管理策略对象。
示例代码:
Spring配置文件 (applicationContext.xml
):
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="bubbleSortStrategy" class="com.example.strategy.BubbleSortStrategy"/><bean id="quickSortStrategy" class="com.example.strategy.QuickSortStrategy"/><bean id="sortingContext" class="com.example.strategy.SortingContext"><constructor-arg ref="bubbleSortStrategy"/></bean>
</beans>
客户端代码示例:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class SortingClient {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 获取上下文SortingContext sortingContext = (SortingContext) context.getBean("sortingContext");// 使用默认策略sortingContext.sortArray(new int[]{10, 5, 8, 3, 7, 9, 1, 2});System.out.println("Sorted using default strategy: " + Arrays.toString(new int[]{10, 5, 8, 3, 7, 9, 1, 2}));// 更换策略SortStrategy quickSortStrategy = (SortStrategy) context.getBean("quickSortStrategy");sortingContext.setSortStrategy(quickSortStrategy);sortingContext.sortArray(new int[]{10, 5, 8, 3, 7, 9, 1, 2});System.out.println("Sorted using Quick Sort: " + Arrays.toString(new int[]{10, 5, 8, 3, 7, 9, 1, 2}));}
}
7.3 策略模式与Spring框架的集成
在Spring框架中,我们可以利用Spring的Bean工厂来配置和管理策略对象,从而简化策略模式的实现。
Spring配置文件 (applicationContext.xml
):
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="creditCardStrategy" class="com.example.strategy.CreditCardStrategy"/><bean id="paypalStrategy" class="com.example.strategy.PayPalStrategy"/><bean id="shoppingCart" class="com.example.strategy.ShoppingCart"><constructor-arg ref="creditCardStrategy"/></bean>
</beans>
客户端代码示例:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class ShoppingCartClient {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 获取购物车上下文ShoppingCart shoppingCart = (ShoppingCart) context.getBean("shoppingCart");// 使用默认策略shoppingCart.checkout(100);System.out.println("Paid using default strategy.");// 更换策略PaymentStrategy paypalStrategy = (PaymentStrategy) context.getBean("paypalStrategy");shoppingCart.setPaymentStrategy(paypalStrategy);shoppingCart.checkout(100);System.out.println("Paid using PayPal.");}
}
8. 常见问题解答
8.1 如何选择合适的策略?
- 评估需求:首先确定应用程序的需求,考虑哪种策略最能满足当前的需求。
- 性能考量:考虑策略的性能影响,选择性能最优的策略。
- 扩展性和维护性:选择易于扩展和维护的策略。
8.2 如何处理策略之间的依赖关系?
- 策略独立:确保每个策略实现都是独立的,尽量避免策略之间的相互依赖。
- 使用依赖注入:如果确实需要依赖关系,可以使用依赖注入框架来管理这些依赖。
9. 性能考量
9.1 性能影响分析
- 对象创建成本:由于策略模式增加了对象的数量,每次创建策略对象可能会带来额外的开销。
- 调用成本:策略模式可能会引入额外的接口调用,这可能会影响性能。
- 策略选择:策略选择的成本也需要考虑,特别是当策略的数量很大时。
9.2 性能优化技巧
- 缓存策略对象:对于不变的策略,可以考虑缓存策略对象以减少重复创建的成本。
- 使用静态工厂方法:使用静态工厂方法来创建策略对象,这样可以避免直接使用new关键字创建对象带来的开销。
- 策略池:对于经常使用的策略,可以考虑使用策略池来复用已有的策略对象。
10. 最佳实践
10.1 何时使用策略模式
- 算法选择:当需要在运行时选择算法时。
- 行为切换:当需要在运行时改变对象的行为时。
10.2 如何避免过度使用策略模式
- 限制策略数量:避免为每个小变化创建策略,只在真正需要的时候使用策略模式。
- 考虑其他模式:如果策略模式不适合当前的问题,可以考虑其他设计模式。
10.3 避免常见陷阱
- 过度设计:不要为了使用策略模式而使用策略模式。
- 依赖过多:确保策略之间的依赖关系最小化。
11. 总结
策略模式的关键点回顾
- 定义:策略模式定义了一系列的算法,把它们一个个封装起来,并且使它们可相互替换。
- 组成部分:包括抽象策略、具体策略和上下文。
- 优点:易于扩展、遵循开闭原则。
- 缺点:增加了对象数量、客户端需要了解所有策略类。
- 设计原则:开闭原则、单一职责原则、里氏替换原则。
- 应用场景:排序算法选择、支付方式选择、优惠券计算等。
- 进阶话题:使用Lambda表达式简化策略模式、与依赖注入框架结合、与Spring框架集成。
本文详细介绍了23种设计模式的基础知识,帮助读者快速掌握设计模式的核心概念,并找到适合实际应用的具体模式:
【设计模式入门】设计模式全解析:23种经典模式介绍与评级指南(设计师必备)