目录
什么叫工厂方法模式
工厂方法模式(Factory Method Pattern)是一种常用的创建型设计模式,它提供了一种将对象的创建逻辑抽象出来的方式,让子类决定实例化哪个具体类。这样可以使得一个类的实例化延迟到其子类,从而达到解耦的目的。
工厂方法模式作用
将对象的创建和使用分离:工厂方法模式将对象的创建过程封装到工厂类中,客户端代码不需要直接实例化具体产品对象,而是通过调用工厂方法来获取对象。这样,客户端代码和具体产品的类之间的耦合度降低,使系统更加灵活和可维护。
支持多态性:工厂方法模式通过抽象工厂和抽象产品的定义,使得客户端代码可以依赖于抽象接口而不是具体类。这鼓励了使用多态性,使得代码更具扩展性和适应性。
实现开闭原则:工厂方法模式符合开闭原则,即对扩展开放,对修改关闭。如果需要添加新的产品类型,只需要创建一个新的具体产品类和对应的具体工厂类,而不需要修改已有的代码,从而确保系统的稳定性。
支持产品家族:工厂方法模式可以创建相关或依赖的产品家族,每个具体工厂都可以创建一组相关的产品。这有助于确保创建的对象之间的一致性和互操作性。
提高代码的可测试性:由于工厂方法模式将对象的创建过程封装在工厂类中,因此在测试时可以轻松地替换具体工厂类的实现,以便进行单元测试或模拟对象的创建过程。
工厂方法模式特征
抽象工厂方法:工厂方法模式通过一个抽象工厂方法(Factory Method)来定义对象的创建接口。这个方法通常位于一个抽象工厂类中,由子类实现,用于创建具体产品对象。这个抽象工厂方法是工厂模式的核心特征之一。
具体工厂类:工厂方法模式中会有多个具体工厂类,每个具体工厂类负责创建特定类型的产品对象。这些具体工厂类都必须实现抽象工厂方法,以便创建产品对象的实例。
抽象产品接口:工厂方法模式定义了一个抽象产品接口(Product),它规定了产品对象应该具有的方法和属性。具体产品类将实现这个抽象产品接口。
具体产品类:工厂方法模式中有多个具体产品类,每个产品类都实现了抽象产品接口,具体定义了产品的行为和属性。
工厂方法模式应用场景
工厂方法模式在软件开发中有广泛的应用场景,特别适用于以下情况:
需要创建多个相关对象:当一个系统需要创建多个相关的对象,而这些对象之间可能存在一些差异,但又有共同的接口时,工厂方法模式非常有用。每个具体工厂负责创建一个特定类型的对象,确保这些对象之间的一致性和互操作性。
延迟对象的创建:有时候需要在需要的时候才创建对象,而不是在程序启动时就创建。工厂方法模式可以将对象的实例化延迟到子类中,只有当客户端真正需要对象时才会创建。
多态性的应用:工厂方法模式鼓励使用多态性,客户端代码依赖于抽象接口而不依赖于具体类。这样可以在运行时选择合适的具体工厂类来创建对象,从而提高了灵活性。
测试和模拟:工厂方法模式有助于测试和模拟对象的创建过程。通过使用工厂方法,可以轻松地替换具体工厂类的实现,以便进行单元测试或模拟对象的创建。
日志记录器和数据库连接池:常见的应用包括日志记录器工厂和数据库连接池工厂。不同的日志记录器或数据库连接池可以由不同的具体工厂来创建,以满足不同的需求。
工厂方法模式的实现
抽象产品接口
- 定义一个接口或抽象类,描述产品对象的共同属性和行为。
- 所有具体产品类都必须实现这个接口或继承这个抽象类。
interface Product {
String operation();
}
创建具体产品类
- 为每个具体的产品创建一个具体产品类。
- 这些类应该实现抽象产品接口,定义产品的具体属性和行为。
class ConcreteProductA implements Product {
@Override
public String operation() {
return "Product A";
}
}
class ConcreteProductB implements Product {
@Override
public String operation() {
return "Product B";
}
}
定义抽象接口
- 定义一个接口或抽象类,包含一个工厂方法的声明,该方法用于创建抽象产品。
- 这个接口将在具体工厂类中被实现。
interface Factory {
Product createProduct();
}
创建具体工厂类
- 为每个具体产品创建一个具体工厂类。
- 这些类实现了抽象工厂接口,负责创建具体产品对象。
class ConcreteFactoryA implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
class ConcreteFactoryB implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}
测试工厂方法
- 客户端代码不直接创建具体产品对象,而是通过具体工厂来获取产品实例。
- 客户端代码应该依赖于抽象工厂接口,以保持灵活性。
public class Main {
public static void clientCode(Factory factory) {
Product product = factory.createProduct();
String result = product.operation();
System.out.println("Client: " + result);
}
public static void main(String[] args) {
Factory factoryA = new ConcreteFactoryA();
clientCode(factoryA);
Factory factoryB = new ConcreteFactoryB();
clientCode(factoryB);
}
}
测试结果:
总结
工厂方法模式的优点:
- 将对象的创建和使用分离,降低了客户端代码与具体类的耦合度。
- 可以轻松扩展和添加新的产品类型,只需要创建新的具体工厂和产品类即可,无需修改现有代码。
- 符合开闭原则,系统对扩展开放,对修改关闭。
工厂方法模式的缺点:
- 增加了类的数量,每个具体产品都需要一个对应的具体工厂类。
- 客户端代码需要知道使用哪个具体工厂,可能需要额外的配置或逻辑来选择合适的工厂。