工厂模式 vs 策略模式:Java设计模式详细对比
设计模式是软件开发中提高系统灵活性、可维护性和可扩展性的有效方法。工厂模式和策略模式是两种常用的设计模式,它们各自有不同的应用场景和优势。本文将详细对比工厂模式和策略模式,通过具体的Java源码示例来帮助理解它们的使用场景和实现方法。
1. 工厂模式概述
1.1 工厂模式的定义
工厂模式(Factory Pattern)是一种创建型设计模式,旨在定义一个用于创建对象的接口,但将对象的实例化推迟到子类中。工厂模式主要解决的问题是如何创建对象,并将对象的创建过程封装起来,使得客户端代码不需要直接涉及对象的创建过程。
1.2 工厂模式的结构
工厂模式主要包含以下角色:
- Product(产品接口):定义了工厂方法所创建的对象的接口。
- ConcreteProduct(具体产品):实现了产品接口的具体产品类。
- Creator(创建者接口):声明了工厂方法的接口。
- ConcreteCreator(具体创建者):实现了工厂方法,返回具体的产品实例。
1.3 工厂模式的UML图
+------------------+
| Product |
+------------------+
| +operation() |
+------------------+
^
|
|
+------------------+ +------------------+
| ConcreteProduct1 | | ConcreteProduct2 |
+------------------+ +------------------+
| +operation() | | +operation() |
+------------------+ +------------------+
+------------------+
| Creator |
+------------------+
| +factoryMethod() |
+------------------+
^
|
|
+------------------+
| ConcreteCreator |
+------------------+
| +factoryMethod() |
+------------------+
1.4 工厂模式的代码示例
下面是一个简单的工厂模式实现示例。我们将创建一个工厂来生成不同类型的动物对象。
java
// Product Interface
public interface Animal {
void speak();
}
// ConcreteProduct1
public class Dog implements Animal {
@Override
public void speak() {
System.out.println("Woof");
}
}
// ConcreteProduct2
public class Cat implements Animal {
@Override
public void speak() {
System.out.println("Meow");
}
}
// Creator
public abstract class AnimalFactory {
public abstract Animal createAnimal();
}
// ConcreteCreator1
public class DogFactory extends AnimalFactory {
@Override
public Animal createAnimal() {
return new Dog();
}
}
// ConcreteCreator2
public class CatFactory extends AnimalFactory {
@Override
public Animal createAnimal() {
return new Cat();
}
}
// Main class to demonstrate
public class Main {
public static void main(String[] args) {
AnimalFactory factory = new DogFactory();
Animal dog = factory.createAnimal();
dog.speak(); // Output: Woof
factory = new CatFactory();
Animal cat = factory.createAnimal();
cat.speak(); // Output: Meow
}
}
2. 策略模式概述
2.1 策略模式的定义
策略模式(Strategy Pattern)是一种行为型设计模式,旨在定义一系列算法,将每一个算法封装起来,并使它们可以互换。策略模式让算法的变化不会影响到使用算法的客户端。
2.2 策略模式的结构
策略模式主要包含以下角色:
- Strategy(策略接口):定义了所有支持的算法的接口。
- ConcreteStrategy(具体策略):实现了策略接口的具体算法。
- Context(上下文):持有一个策略对象的引用,并可以通过调用策略对象的方法来执行算法。
2.3 策略模式的UML图
+------------------+
| Strategy |
+------------------+
| +execute() |
+------------------+
^
|
|
+------------------+ +------------------+
| ConcreteStrategy1| | ConcreteStrategy2|
+------------------+ +------------------+
| +execute() | | +execute() |
+------------------+ +------------------+
+------------------+
| Context |
+------------------+
| -strategy: Strategy|
| +setStrategy() |
| +performAction() |
+------------------+
2.4 策略模式的代码示例
下面是一个简单的策略模式实现示例。我们将创建不同的支付策略,并根据选择的支付策略来执行支付操作。
java
// Strategy Interface
public interface PaymentStrategy {
void pay(int amount);
}
// ConcreteStrategy1
public class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
public CreditCardPayment(String cardNumber) {
this.cardNumber = cardNumber;
}
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using credit card: " + cardNumber);
}
}
// ConcreteStrategy2
public class PayPalPayment implements PaymentStrategy {
private String email;
public PayPalPayment(String email) {
this.email = email;
}
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using PayPal: " + email);
}
}
// Context
public class ShoppingCart {
private PaymentStrategy strategy;
public void setPaymentStrategy(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void checkout(int amount) {
strategy.pay(amount);
}
}
// Main class to demonstrate
public class Main {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
// Using credit card payment strategy
cart.setPaymentStrategy(new CreditCardPayment("1234-5678-9876-5432"));
cart.checkout(100); // Output: Paid 100 using credit card: 1234-5678-9876-5432
// Using PayPal payment strategy
cart.setPaymentStrategy(new PayPalPayment("user@example.com"));
cart.checkout(200); // Output: Paid 200 using PayPal: user@example.com
}
}
3. 工厂模式与策略模式的对比
3.1 目的与应用场景
-
工厂模式:
- 目的:解决对象创建的问题,将对象的实例化推迟到子类中。
- 应用场景:当一个类无法预见它需要创建的对象的类时,可以使用工厂模式。适用于对象创建过程复杂,或者有多个子类需要创建的情况。
-
策略模式:
- 目的:解决算法的选择问题,将算法封装在不同的策略类中,并在运行时选择合适的策略。
- 应用场景:当系统中有多个算法需要切换时,可以使用策略模式。适用于算法可以互换,且算法的实现可能会经常变化的情况。
3.2 设计结构
-
工厂模式:
- 主要涉及到工厂类的创建和具体产品的实例化,工厂类负责创建具体产品。
- 对象创建和具体产品的选择是通过工厂类来完成的,客户端代码无需了解具体产品的创建过程。
-
策略模式:
- 主要涉及到策略接口和具体策略的实现,策略模式通过上下文类来选择具体的策略对象。
- 算法的实现和选择是通过上下文类来完成的,客户端代码无需了解具体策略的实现细节。
3.3 灵活性与扩展性
-
工厂模式:
- 灵活性:可以通过扩展工厂类来支持新的产品类型,不需要修改客户端代码。
- 扩展性:容易扩展新的产品类型,但需要在工厂类中增加对应的创建逻辑。
-
策略模式:
- 灵活性:可以通过扩展策略接口来增加新的策略算法,不需要修改上下文类。
- 扩展性:容易扩展新的算法实现,但策略类之间的协作需要通过上下文类来管理。
3.4 示例代码对比
- 工厂模式 示例中的
AnimalFactory
负责创建Dog
和Cat
对象,而客户端只需要使用工厂方法来获取具体的动物对象。 - 策略模式 示例中的
ShoppingCart
负责管理不同的支付策略,客户端可以通过设置不同的策略来进行支付操作。
4. 总结
工厂模式和策略模式在软件设计中扮演着不同的角色。工厂模式专注于对象创建,将创建逻辑封装到工厂类中,而策略模式专注于算法的选择和切换,通过上下文类来选择合适的策略。理解这两种模式的核心概念和适用场景,有助于在实际开发中选择合适的模式来提高系统的灵活性和可维护性。
通过对工厂模式和策略模式的详细对比,希望本文能帮助你在实际项目中更好地运用
这些设计模式,从而提升系统的设计质量和可扩展性。