工厂模式(Factory Pattern)和策略模式(Strategy Pattern)都是常见的设计模式,但它们解决的问题和应用场景不同。下面是它们的区别:
1. 目的不同:
-
工厂模式(Factory Pattern):
工厂模式的主要目的是创建对象。它通过定义一个创建对象的接口,让子类决定实例化哪一个具体类,从而将对象创建的逻辑与使用的代码分离。
工厂模式可以分为简单工厂、工厂方法和抽象工厂三种类型:
- 简单工厂:通过一个工厂类来根据条件创建具体对象。
- 工厂方法:定义一个工厂接口,并让具体的子类决定创建哪种对象。
- 抽象工厂:提供多个相关对象的创建接口。
使用场景:当需要在程序中通过统一接口创建不同类型的对象时使用。
-
策略模式(Strategy Pattern):
策略模式的主要目的是改变行为。它定义了一系列算法,将每个算法封装起来,使得它们可以相互替换。客户端根据需要选择具体的算法或策略。
策略模式的关键是:允许在运行时根据不同的需求动态地选择某种行为或算法,而不需要修改客户端代码。
使用场景:当有多个算法可以完成同样的工作,并且需要在运行时动态选择时使用。
2. 实现结构不同:
-
工厂模式:
- 包含一个工厂类(或工厂方法),用于创建对象。
- 用户通过工厂类获取对象的实例,不需要直接使用构造函数。
- 类似于:对象的创建委托给工厂。
示例:
javainterface Product { } class ConcreteProductA implements Product { } class ConcreteProductB implements Product { } class ProductFactory { public Product createProduct(String type) { if (type.equals("A")) { return new ConcreteProductA(); } else if (type.equals("B")) { return new ConcreteProductB(); } return null; } }
-
策略模式:
- 包含一组算法或策略类,每个类实现相同的接口,但提供不同的算法实现。
- 用户根据需求选择具体的策略类来调用。
- 类似于:行为的替换由策略控制。
示例:
javainterface Strategy { void execute(); } class ConcreteStrategyA implements Strategy { public void execute() { System.out.println("Strategy A"); } } class ConcreteStrategyB implements Strategy { public void execute() { System.out.println("Strategy B"); } } class Context { private Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void executeStrategy() { strategy.execute(); } }
3. 关注点不同:
- 工厂模式 关注的是如何创建对象。它解决了对象的创建逻辑,使得客户端不需要关心对象的具体创建过程。
- 策略模式 关注的是如何动态选择行为。它将不同的算法封装在独立的类中,并通过组合的方式让客户端可以在运行时灵活选择算法。
4. 典型应用场景:
-
工厂模式:
- 需要创建大量相似类型的对象。
- 根据不同的条件,生成不同类型的对象。
- 抽象出对象的创建过程,以提高代码的可扩展性和维护性。
-
策略模式:
- 需要在不同情况下选择不同的算法或行为。
- 需要动态地切换算法,避免代码中出现大量的
if-else
或switch
语句。 - 提供一组可互换的行为,并根据上下文决定具体使用哪一个。
小的总结:
- 工厂模式 解决的是对象创建问题,主要用于创建复杂对象或提供统一的创建接口。
- 策略模式 解决的是行为选择问题,主要用于动态选择和替换算法或策略。
以下案例:电子商务系统中的支付处理
假设我们正在设计一个电子商务系统,其中用户可以通过多种支付方式完成购买,例如信用卡、PayPal、比特币等。系统需要能够处理不同的支付方式,并且在运行时能够灵活地选择和切换支付策略。
1. 工厂模式用于创建支付策略
首先,我们可以使用工厂模式来创建不同的支付策略对象。工厂模式在这里的作用是根据支付方式的不同来生成相应的支付处理策略对象。
步骤:
-
定义支付策略接口(Strategy):
javainterface PaymentStrategy { void pay(double amount); }
-
实现具体支付策略(ConcreteStrategy):
javaclass CreditCardPayment implements PaymentStrategy { private String cardNumber; private String cardHolder; public CreditCardPayment(String cardNumber, String cardHolder) { this.cardNumber = cardNumber; this.cardHolder = cardHolder; } @Override public void pay(double amount) { System.out.println("Paid " + amount + " using Credit Card."); } } class PayPalPayment implements PaymentStrategy { private String email; public PayPalPayment(String email) { this.email = email; } @Override public void pay(double amount) { System.out.println("Paid " + amount + " using PayPal."); } }
-
定义支付策略工厂接口(Factory):
javainterface PaymentFactory { PaymentStrategy createPaymentStrategy(); }
-
实现具体支付策略工厂(Concrete Factory):
javaclass CreditCardPaymentFactory implements PaymentFactory { private String cardNumber; private String cardHolder; public CreditCardPaymentFactory(String cardNumber, String cardHolder) { this.cardNumber = cardNumber; this.cardHolder = cardHolder; } @Override public PaymentStrategy createPaymentStrategy() { return new CreditCardPayment(cardNumber, cardHolder); } } class PayPalPaymentFactory implements PaymentFactory { private String email; public PayPalPaymentFactory(String email) { this.email = email; } @Override public PaymentStrategy createPaymentStrategy() { return new PayPalPayment(email); } }
2. 策略模式用于处理支付逻辑
接下来,策略模式用于实际处理支付逻辑。我们可以在系统中定义一个上下文类,它持有一个策略对象,并且委托策略对象执行支付操作。
步骤:
-
定义支付上下文(Context):
javaclass PaymentContext { private PaymentStrategy paymentStrategy; public PaymentContext(PaymentStrategy paymentStrategy) { this.paymentStrategy = paymentStrategy; } public void executePayment(double amount) { paymentStrategy.pay(amount); } }
-
在客户端使用工厂模式和策略模式:
javapublic class PaymentDemo { public static void main(String[] args) { // 根据用户选择创建支付策略工厂 PaymentFactory paymentFactory; PaymentStrategy paymentStrategy; // 模拟用户选择信用卡支付 paymentFactory = new CreditCardPaymentFactory("1234-5678-9876-5432", "John Doe"); paymentStrategy = paymentFactory.createPaymentStrategy(); PaymentContext paymentContext = new PaymentContext(paymentStrategy); paymentContext.executePayment(150.0); // 模拟用户选择PayPal支付 paymentFactory = new PayPalPaymentFactory("user@example.com"); paymentStrategy = paymentFactory.createPaymentStrategy(); paymentContext = new PaymentContext(paymentStrategy); paymentContext.executePayment(250.0); } }
总结
-
工厂模式在这个示例中负责创建不同的支付策略对象(如信用卡支付、PayPal支付等)。它封装了创建策略的细节,使得客户端代码只需要关注策略的使用,而不需要了解创建策略的复杂过程。
-
策略模式则用于定义和实现不同的支付处理逻辑。通过策略模式,我们可以在运行时动态选择支付方式,并将支付逻辑封装在具体的策略实现中。
通过结合这两种模式,我们能够创建一个灵活且易于扩展的支付处理系统。工厂模式确保了支付策略的创建过程的统一性和一致性,而策略模式则确保了支付逻辑的灵活性和可替换性。