工厂模式和策略模式确实在某些场景下会有类似之处,但它们的意图和应用场景是不同的。以下是详细的对比与区分:
1. 定义与意图
工厂模式
- 定义:工厂模式通过定义一个工厂类,封装对象的创建过程,并根据需求返回不同的对象实例。
- 意图:
-
- 关注对象的创建过程。
- 将复杂的对象创建逻辑封装起来,调用者不需要直接使用
new
操作来实例化对象。
策略模式
- 定义:策略模式定义一系列算法,将它们封装到独立的策略类中,并通过上下文类在运行时选择或切换不同的策略。
- 意图:
-
- 关注行为或算法的封装和动态切换。
- 提供不同的策略实现,支持动态切换和扩展。
2. 使用场景
工厂模式的使用场景
- 需要创建对象,并对对象的创建过程进行封装。
- 对象创建过程可能包含复杂的逻辑(如反射、参数配置等)。
- 需要通过工厂类屏蔽对象实例化的具体细节。
示例:
创建数据库连接池,根据配置返回不同的连接池实例。
策略模式的使用场景
- 系统中存在多个可替代的算法或行为,需要在运行时根据条件动态选择。
- 希望通过接口定义算法,避免硬编码的
if-else
或switch
语句。 - 需要灵活地增加或替换算法,而不影响已有代码。
示例:
支付系统中,不同的支付方式(如支付宝、微信)需要不同的实现。
3. 结构对比
工厂模式结构
- 主要涉及:
-
- 工厂类:负责对象的创建。
- 产品类(接口或抽象类) :由工厂返回的实例实现。
- 核心角色:工厂类集中封装对象创建逻辑。
示例:
typescript 代码解读复制代码// 抽象产品
interface Product {
void use();
}
// 具体产品
class ConcreteProductA implements Product {
public void use() {
System.out.println("使用产品A");
}
}
class ConcreteProductB implements Product {
public void use() {
System.out.println("使用产品B");
}
}
// 工厂类
class Factory {
public static Product createProduct(String type) {
if ("A".equals(type)) {
return new ConcreteProductA();
} else if ("B".equals(type)) {
return new ConcreteProductB();
}
throw new IllegalArgumentException("未知类型");
}
}
// 客户端
public class FactoryExample {
public static void main(String[] args) {
Product product = Factory.createProduct("A");
product.use();
}
}
策略模式结构
- 主要涉及:
-
- 策略接口:定义算法的公共接口。
- 具体策略类:每个策略类实现不同的算法或行为。
- 上下文类:持有策略对象,并调用策略方法。
- 核心角色:策略类封装了具体的算法或行为。
示例:
java 代码解读复制代码// 策略接口
interface PaymentStrategy {
void pay(double amount);
}
// 具体策略
class AlipayPayment implements PaymentStrategy {
public void pay(double amount) {
System.out.println("使用支付宝支付: ¥" + amount);
}
}
class WeChatPayment implements PaymentStrategy {
public void pay(double amount) {
System.out.println("使用微信支付: ¥" + amount);
}
}
// 上下文类
class PaymentContext {
private PaymentStrategy strategy;
public void setStrategy(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void pay(double amount) {
if (strategy == null) {
throw new IllegalStateException("未设置支付策略");
}
strategy.pay(amount);
}
}
// 客户端
public class StrategyExample {
public static void main(String[] args) {
PaymentContext context = new PaymentContext();
context.setStrategy(new AlipayPayment());
context.pay(100.0);
context.setStrategy(new WeChatPayment());
context.pay(200.0);
}
}
4. 核心区别
维度 | 工厂模式 | 策略模式 |
---|---|---|
核心关注点 | 对象的创建:解决“创建什么对象”的问题。 | 算法或行为的选择:解决“执行什么策略”的问题。 |
动态性 | 一般在对象创建时选择具体产品类型,之后不会切换。 | 在运行时可以随时切换策略,实现动态行为。 |
扩展性 | 通过增加新的工厂或产品类扩展对象创建逻辑。 | 通过增加新的策略类扩展行为,且对上下文代码无影响。 |
典型应用场景 | - JDBC 的 DriverManager 工厂模式。 - Spring 的 Bean 工厂。 | - 支付系统选择不同支付方式。 - 日志记录选择不同输出方式。 - 不同排序算法。 |
类的关系 | 客户端调用工厂,工厂决定返回哪个产品类的实例。 | 客户端持有上下文,上下文通过组合策略对象决定调用哪个策略的行为。 |
解决的问题 | 统一封装复杂对象创建过程,避免直接使用 new ,降低对象创建的复杂性。 | 消除冗长的 if-else 代码,提供算法或行为的动态选择机制,提升代码灵活性和可扩展性。 |
5. 实际应用中的结合
工厂模式和策略模式可以结合使用:
- 工厂模式用于创建策略实例,策略模式用于动态选择和执行策略。
- 示例:支付系统中:
-
- 使用工厂模式创建支付策略实例(如
AlipayPayment
或WeChatPayment
)。 - 使用策略模式在上下文中动态切换策略,执行支付行为。
- 使用工厂模式创建支付策略实例(如
typescript 代码解读复制代码// 工厂类
class PaymentFactory {
public static PaymentStrategy getPaymentStrategy(String type) {
if ("Alipay".equalsIgnoreCase(type)) {
return new AlipayPayment();
} else if ("WeChat".equalsIgnoreCase(type)) {
return new WeChatPayment();
}
throw new IllegalArgumentException("未知支付类型");
}
}
// 客户端使用
public class CombinedExample {
public static void main(String[] args) {
PaymentStrategy strategy = PaymentFactory.getPaymentStrategy("Alipay");
strategy.pay(100.0);
strategy = PaymentFactory.getPaymentStrategy("WeChat");
strategy.pay(200.0);
}
}
输出:
makefile 代码解读复制代码使用支付宝支付: ¥100.0
使用微信支付: ¥200.0
总结
- 工厂模式:用于创建对象,重点在于“生产什么对象”。
- 策略模式:用于动态切换算法或行为,重点在于“执行什么行为”。
- 区别:工厂模式是创建型模式,而策略模式是行为型模式。
- 结合使用:在需要动态选择算法的场景,可以通过工厂模式生成策略实例,然后结合策略模式动态切换策略。
评论记录:
回复评论: