目录
工厂模式和策略模式是两种常见的设计模式,解决的是不同的问题,适用于不同的场景。下面详细介绍这两者的区别:
目的不同
- 工厂模式(Factory Pattern) 的主要目的是创建对象。它将对象的创建过程封装起来,使得客户端不需要直接实例化对象,而是通过工厂方法来获取对象。这样做可以提高代码的灵活性,便于扩展和维护。
- 策略模式(Strategy Pattern) 则侧重于行为的选择。它允许你定义一系列算法或策略,并且在运行时动态选择某个具体策略来执行。策略模式的核心思想是通过不同的策略类实现同一个接口,达到算法的可替换性。
结构不同
-
工厂模式 通常包含一个工厂类,它根据某些条件(如输入参数)来决定创建哪种具体的对象。常见的工厂模式有简单工厂模式、工厂方法模式 和 抽象工厂模式。
- 例如:一个汽车工厂根据客户的要求生产不同品牌的汽车(如宝马、奔驰等),客户不需要知道如何创建这些汽车,直接向工厂请求即可。
-
策略模式 则由一个策略接口和一系列具体的策略实现类组成。它的结构是用组合的方式来替代继承,使得可以在运行时通过传入不同的策略对象来决定使用哪种算法。
- 例如:支付系统中可以有不同的支付方式(如信用卡、支付宝、微信支付),这些支付方式实现相同的支付接口,用户可以在运行时选择不同的支付策略。
应用场景
-
工厂模式 适用于对象创建复杂,并且需要通过某种机制来管理不同类型对象的场景。例如,涉及多个子类或具体类的对象创建过程。
典型场景:数据库连接池、日志系统、图形界面中的控件创建等。
-
策略模式 适用于需要在不同情况下选择不同算法或行为的场景,并且这些算法或行为具有相似的接口。策略模式可以减少大量的条件判断,使代码更简洁和灵活。
典型场景:排序算法、加密算法、不同格式文件的解析等。
对比工厂模式和策略模式的主要特点和区别
特征 | 工厂模式(Factory Pattern) | 策略模式(Strategy Pattern) |
---|---|---|
类型 | 创建型设计模式 | 行为型设计模式 |
目标 | 封装对象的创建过程,使得创建过程与使用对象的过程分离。 | 定义一系列的算法,并将每个算法封装起来,使它们可以互相替换。 |
解决问题 | 当系统不应暴露创建对象的具体逻辑给客户端时。 | 当多个行为或算法相似但又有细微差别,需要在运行时动态选择使用哪一个时。 |
主要作用 | 将创建对象的责任从客户端转移到工厂类。 | 提供了算法族的选择性封装,让算法的变化独立于使用算法的客户端。 |
实现 | 通过创建一个工厂类来生成产品对象。 | 通过定义一个策略接口或抽象类以及实现该接口或继承该抽象类的具体策略类。 |
优点 | 隐藏了创建对象的细节。 客户端不需要知道具体的产品类。 符合开闭原则,易于扩展。 | 多个策略类可以互换使用,策略对象可复用。 策略模式提供了管理相关算法族的办法。 符合开闭原则。 |
缺点 | 如果产品等级结构改变,那么需要修改工厂类。 | 客户端必须理解所有策略算法的区别,以便适当选择合适的策略类。 |
适用场景 | 当不知道实例化哪个具体类时。 当一个系统应该独立于它的产品创建、构成和表示时。 当一个类希望由它的子类来指定它所创建的对象时。 | 许多相关的类仅仅是行为有异。 算法使用若用户可以选择不同的实现方式。 算法独立于使用它的客户而变化。 |
工厂模式示例
定义接口或抽象类作为产品的基类,定义具体的产品类及一个工厂类来创建这些产品。
// 抽象产品类
interface Product {
void show();
}
// 具体产品类
class ConcreteProductA implements Product {
@Override
public void show() {
System.out.println("这是产品A");
}
}
class ConcreteProductB implements Product {
@Override
public void show() {
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();
}
return null;
}
}
public class FactoryPatternDemo {
public static void main(String[] args) {
// 使用工厂类创建产品
Product productA = Factory.createProduct("A");
productA.show();
Product productB = Factory.createProduct("B");
productB.show();
}
}
策略模式示例
定义策略接口或抽象类、几个实现该接口或继承了该抽象类的具体策略类,最后定义一个上下文环境类来使用这些策略。
// 策略接口
interface Strategy {
void algorithmInterface();
}
// 具体策略类
class ConcreteStrategyA implements Strategy {
@Override
public void algorithmInterface() {
System.out.println("算法A的实现");
}
}
class ConcreteStrategyB implements Strategy {
@Override
public void algorithmInterface() {
System.out.println("算法B的实现");
}
}
// 上下文环境类
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void executeStrategy() {
strategy.algorithmInterface();
}
}
public class StrategyPatternDemo {
public static void main(String[] args) {
Context context = new Context(new ConcreteStrategyA());
context.executeStrategy();
context.setStrategy(new ConcreteStrategyB());
context.executeStrategy();
}
}
这两个例子展示了工厂模式和策略模式的基本实现方式。工厂模式通过工厂类来创建产品对象,而策略模式通过策略接口和具体策略类来定义一组可以互换的算法或行为。在实际应用中,可以根据需要选择合适的设计模式来优化代码结构,提高代码的可维护性和扩展性。