工厂模式 vs 策略模式对比表格
对比维度 | 工厂模式(Factory Pattern) | 策略模式(Strategy Pattern) |
---|---|---|
意图 | 通过一个接口或抽象类来创建对象,隐藏具体类的实现细节。 | 定义一系列算法,封装每个算法,并使它们可以互相替换。 |
使用场景 | 需要动态决定实例化哪个具体类,并且避免直接使用new 。 | 需要在运行时动态选择算法或行为,避免条件判断。 |
参与者 | 工厂接口、具体工厂类、产品接口、具体产品类。 | 策略接口、具体策略类、上下文类。 |
类之间的关系 | 工厂类与产品类通过依赖抽象产品接口进行解耦。 | 上下文类持有策略接口引用,策略类实现策略接口。 |
设计原则 | 依赖倒置、开闭原则。 | 单一职责、开闭原则、依赖倒置。 |
实际应用 | 对象的创建,如数据库连接池、日志记录器等。 | 算法的切换,如排序算法、支付方式等。 |
组合使用 | 可以结合策略模式使用,工厂模式创建策略对象。 | 可以通过工厂模式动态创建不同的策略对象。 |
维护性 | 集中化管理对象创建,便于扩展和维护。 | 动态切换算法,避免冗长条件判断,易于扩展。 |
图示化对比
1. 工厂模式图示:
- 参与者:
- 工厂接口
Factory
- 具体工厂类
ConcreteFactory
- 产品接口
Product
- 具体产品类
ConcreteProduct
- 工厂接口
+------------------+
| Client |
+--------+---------+
|
v
+--------+---------+
| Factory |<----------------------+
+--------+---------+ |
| |
v |
+--------+---------+ +------+---------+
| ConcreteFactory | | Product |
+------------------+ +--------+--------+
| |
v v
+------------------+ +-----------------+
| ConcreteProduct | |ConcreteProductA |
+------------------+ +-----------------+
2. 策略模式图示:
- 参与者:
- 策略接口
Strategy
- 具体策略类
ConcreteStrategy
- 上下文类
Context
- 策略接口
+------------------+
| Client |
+--------+---------+
|
v
+--------+---------+
| Context |<----------------------+
+--------+---------+ |
| |
v |
+--------+---------+ +------+---------+
| Strategy | |ConcreteStrategy |
+--------+---------+ +-----------------+
| ^
v |
+------------------+ +------+---------+
| ConcreteStrategy | |ConcreteStrategyB|
+------------------+ +-----------------+
Java代码示例
1. 工厂模式代码示例:
// 产品接口
interface Product {
void use();
}
// 具体产品类A
class ConcreteProductA implements Product {
@Override
public void use() {
System.out.println("Using Product A");
}
}
// 具体产品类B
class ConcreteProductB implements Product {
@Override
public void use() {
System.out.println("Using Product B");
}
}
// 工厂接口
interface Factory {
Product createProduct();
}
// 具体工厂类A
class ConcreteFactoryA implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
// 具体工厂类B
class ConcreteFactoryB implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}
// 客户端代码
public class FactoryPatternDemo {
public static void main(String[] args) {
Factory factoryA = new ConcreteFactoryA();
Product productA = factoryA.createProduct();
productA.use(); // 输出: Using Product A
Factory factoryB = new ConcreteFactoryB();
Product productB = factoryB.createProduct();
productB.use(); // 输出: Using Product B
}
}
2. 策略模式代码示例:
// 策略接口
interface Strategy {
void execute();
}
// 具体策略类A
class ConcreteStrategyA implements Strategy {
@Override
public void execute() {
System.out.println("Executing Strategy A");
}
}
// 具体策略类B
class ConcreteStrategyB implements Strategy {
@Override
public void execute() {
System.out.println("Executing Strategy B");
}
}
// 上下文类
class Context {
private Strategy strategy;
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void executeStrategy() {
strategy.execute();
}
}
// 客户端代码
public class StrategyPatternDemo {
public static void main(String[] args) {
Context context = new Context();
context.setStrategy(new ConcreteStrategyA());
context.executeStrategy(); // 输出: Executing Strategy A
context.setStrategy(new ConcreteStrategyB());
context.executeStrategy(); // 输出: Executing Strategy B
}
}
补充论证
-
扩展性:在实际项目中,工厂模式和策略模式都能提供良好的扩展性。工厂模式可以轻松添加新的产品类型,而无需修改现有代码。策略模式则允许添加新的算法,而无需改变上下文类的代码。
-
可测试性:这两种模式都提高了代码的可测试性。工厂模式使得对象创建过程更加集中和统一,便于进行单元测试。策略模式则将算法的实现与使用分离,可以分别测试每个策略类。
-
解耦性:工厂模式通过将对象创建的责任从客户端转移到工厂类,实现了对象创建过程与使用过程的解耦。策略模式通过将算法的选择与实现分离,使得上下文类不需要了解具体的算法实现,从而实现了行为与策略的解耦。
这些特性使得工厂模式和策略模式在软件开发中得到了广泛应用,尤其在复杂的业务逻辑处理和面向对象的设计中,能够帮助开发者构建更加灵活、可维护的系统结构。