策略模式和状态模式都是行为型设计模式,但是它们的应用场景和实现方式不同。策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。而状态模式是用于处理对象在内部状态改变时,改变其行为的场景。
在编程领域,我们需要面对各种各样的问题,有些问题可以通过简单的逻辑实现,而有些问题则需要更加复杂的解决方案,策略模式(Strategy Pattern)就是这样一种设计灵活、可扩展的解决方案,它可以帮助我们在面对复杂问题时,将问题的解决过程抽象为一系列可复用的策略类,从而提高代码的可维护性和可扩展性。
策略模式的核心思想是定义一系列算法,并将每个算法封装在一个具有共同接口的独立类中,使得它们可以相互替换,策略模式让算法的变化独立于使用它们的客户端。
下面我们通过一个简单的例子来说明策略模式的使用,假设我们有一个电商系统,需要根据不同的促销活动计算商品的价格,在这个例子中,我们可以将促销活动抽象为一个策略类,而具体的促销活动实现则作为这个策略类的子类。
我们定义一个促销策略接口:
public interface PromotionStrategy { double calculatePrice(double originalPrice); }
我们创建两个具体的促销活动实现类,分别表示满减和折扣两种促销活动:
public class FullReductionPromotion implements PromotionStrategy { @Override public double calculatePrice(double originalPrice) { // 实现满减逻辑 return originalPrice; } } public class DiscountPromotion implements PromotionStrategy { private double discountRate; public DiscountPromotion(double discountRate) { this.discountRate = discountRate; } @Override public double calculatePrice(double originalPrice) { // 实现折扣逻辑 return originalPrice * (1 - discountRate); } }
我们定义一个上下文类,用于根据不同的促销活动选择合适的策略:
public class ShoppingCart { private PromotionStrategy promotionStrategy; private double originalPrice; private double price; public ShoppingCart(double originalPrice, PromotionStrategy promotionStrategy) { this.originalPrice = originalPrice; this.promotionStrategy = promotionStrategy; } public void setPromotionStrategy(PromotionStrategy promotionStrategy) { this.promotionStrategy = promotionStrategy; } public void execute() { price = promotionStrategy.calculatePrice(originalPrice); } }
我们可以在客户端代码中使用策略模式:
public class Client { public static void main(String[] args) { ShoppingCart shoppingCart = new ShoppingCart(100, new FullReductionPromotion()); shoppingCart.execute(); // 不使用折扣活动,价格为100元 System.out.println("原价:" + shoppingCart.originalPrice); // 原价为100元,未使用折扣活动,价格不变 ; shoppingCart.setPromotionStrategy(new DiscountPromotion(0.8)); // 使用8折活动,计算新价格并输出结果 System.out.println("新价格:" + shoppingCart.price); // 结果应为80元,使用了8折活动后的价格为80元 } }
通过以上示例,我们可以看到策略模式在处理复杂问题时的优越性,当我们需要添加新的促销活动时,只需要创建一个新的策略类并实现相应的接口即可,无需修改现有的代码,客户端代码也不需要关心具体的策略实现细节,只需调用相应的方法即可,这样一来,我们的代码变得更加灵活、可扩展和易于维护。