1. 设计模式-策略模式
策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,并将每一个算法封装起来,使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户。在策略模式中,一个类的行为或其算法可以在运行时更改,这种更改是通过改变其行为对象来实现的。
策略模式的关键在于定义一系列的算法接口,以及具体实现这些算法的一组类。客户端通过持有策略接口的引用,可以在运行时根据需要动态地切换不同的策略(算法)实现。
假设我们有一个简单的购物车结算系统,其中不同的用户类型有不同的折扣策略。
2. 策略接口
public interface DiscountStrategy {
double calculateDiscount(double price);
}
3. 具体策略类
class RegularDiscount implements DiscountStrategy {
@Override
public double calculateDiscount(double price) {
return price * 0.9; // 普通用户9折
}
}
class VIPDiscount implements DiscountStrategy {
@Override
public double calculateDiscount(double price) {
return price * 0.8; // VIP用户8折
}
}
class SuperVIPDiscount implements DiscountStrategy {
@Override
public double calculateDiscount(double price) {
return price * 0.7; // 超级VIP用户7折
}
}
4. 上下文类
class ShoppingCart {
private DiscountStrategy discountStrategy;
private double total;
public ShoppingCart(DiscountStrategy strategy) {
this.discountStrategy = strategy;
}
public void setDiscountStrategy(DiscountStrategy strategy) {
this.discountStrategy = strategy;
}
public void addItem(double price) {
total += price;
}
public double checkout() {
double discountedPrice = discountStrategy.calculateDiscount(total);
total = 0; // 结算后清零总金额
return discountedPrice;
}
}
5. 使用示例
public class Main {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart(new RegularDiscount());
cart.addItem(100);
System.out.println("Regular Discount: " + cart.checkout());
cart.setDiscountStrategy(new VIPDiscount());
cart.addItem(200);
System.out.println("VIP Discount: " + cart.checkout());
cart.setDiscountStrategy(new SuperVIPDiscount());
cart.addItem(300);
System.out.println("Super VIP Discount: " + cart.checkout());
}
}
策略模式非常适合处理算法或策略在运行时需要动态切换的场景。它通过将算法与使用算法的客户端分离,提高了代码的灵活性和可维护性。然而,策略模式的使用需要权衡策略数量带来的复杂度问题,以及如何有效地管理策略类,避免客户端因直接依赖所有策略而变得复杂。总的来说,策略模式是解决多算法选择问题的有效工具,但在设计时应考虑其适用场景和潜在的复杂性增加。
6. 优点
- 算法的封装与复用:每个策略都是一个独立的类,易于理解和复用。
- 运行时切换策略:客户端可以在运行时动态改变策略,提高了程序的灵活性和扩展性。
- 遵循开闭原则:新增策略时,不需要修改原有代码,符合开闭原则。
7. 缺点
- 策略类数量增加:如果策略数量过多,可能会导致类的数量激增,增加系统的复杂度。
- 所有策略都需要对外暴露:客户端需要知道所有策略的存在,选择合适的策略,这在某些情况下可能会增加客户端的负担。