工厂方法模式,它是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。
它定义了一个用于创建对象的工厂接口,让子类决定实例化哪个类。在工厂方法模式中,父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。这种模式将类实例化操作延迟到子类中完成,即由子类来决定究竟应该实例化哪个类。
工厂方法模式的创建步骤如下:
1、创建抽象工厂类,定义具体工厂的公共接口。
2、创建抽象产品类,定义具体产品的公共接口。
3、创建具体产品类,继承抽象产品类并定义具体产品的生产。
4、创建具体工厂类,继承抽象工厂类并定义创建对应具体产品实例的方法。
5、外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例。
工厂方法模式的优点,主要包括:
1、增加新的产品类时无需修改现有系统:当需要增加一个新的产品时,只需要创建一个新的具体工厂和具体产品类,符合“开放-封闭”原则,增加了系统的灵活性和可扩展性。
2、封装了产品对象的创建细节:客户端只需要使用具体工厂类创建产品对象,无需关心对象是如何被创建的,这样就可以将产品对象的创建细节封装在具体工厂类中。
3、系统具有良好的灵活性和可扩展性:通过使用工厂方法模式,可以在不改变现有客户端代码的情况下,增加或修改产品类和工厂类,具有较强的灵活性。
工厂方法模式的缺点,主要包括:
1、增加额外的编写工作量:在增加新产品时,需要编写新的具体产品类和对应的具体工厂类,增加了系统的复杂度,需要更多的类需要编译和运行,给系统带来一些额外的开销。
2、需要考虑系统的抽象性和理解难度:为了增加系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。

以下是一个示例,展示了如何在C#中实现工厂方法模式:
- // 产品的抽象类
- public abstract class Product
- {
- public abstract void Use();
- }
-
- // 具体产品类1
- public class ConcreteProduct1 : Product
- {
- public override void Use()
- {
- Console.WriteLine("使用具体产品1");
- }
- }
-
- // 具体产品类2
- public class ConcreteProduct2 : Product
- {
- public override void Use()
- {
- Console.WriteLine("使用具体产品2");
- }
- }
-
- // 工厂的抽象类
- public abstract class Creator
- {
- // 工厂方法,由子类实现具体的创建逻辑
- public abstract Product CreateProduct();
- }
-
- // 具体工厂类1
- public class ConcreteCreator1 : Creator
- {
- public override Product CreateProduct()
- {
- return new ConcreteProduct1();
- }
- }
-
- // 具体工厂类2
- public class ConcreteCreator2 : Creator
- {
- public override Product CreateProduct()
- {
- return new ConcreteProduct2();
- }
- }
-
- class Program
- {
- static void Main(string[] args)
- {
- Creator creator1 = new ConcreteCreator1();
- Product product1 = creator1.CreateProduct();
- product1.Use();
-
- Creator creator2 = new ConcreteCreator2
- Product product2 = creator2.CreateProduct();
- product2.Use();
- }
- }
以下是一个示例,展示了如何在Java中实现工厂方法模式:
- // 抽象产品类
- public abstract class Product {
- public abstract void use();
- }
-
- // 具体产品类1
- public class ConcreteProduct1 extends Product {
- @Override
- public void use() {
- System.out.println("使用具体产品1");
- }
- }
-
- // 具体产品类2
- public class ConcreteProduct2 extends Product {
- @Override
- public void use() {
- System.out.println("使用具体产品2");
- }
- }
-
- // 抽象工厂类
- public abstract class Factory {
- // 工厂方法,由子类实现具体的创建逻辑
- public abstract Product createProduct();
- }
-
- // 具体工厂类1
- public class ConcreteFactory1 extends Factory {
- @Override
- public Product createProduct() {
- return new ConcreteProduct1();
- }
- }
-
- // 具体工厂类2
- public class ConcreteFactory2 extends Factory {
- @Override
- public Product createProduct() {
- return new ConcreteProduct2();
- }
- }
-
- // Client代码
- public class Client {
- public static void main(String[] args) {
- Factory factory = new ConcreteFactory1(); // 可以根据实际需要更换为ConcreteFactory2
- Product product = factory.createProduct();
- product.use();
- }
- }
在JavaScript中,工厂方法模式通常可以通过构造函数和对象字面量的组合来实现。
- // 抽象产品类
- class Product {
- // 抽象方法
- use() {
- throw new Error('Use abstract method "use"');
- }
- }
-
- // 具体产品类1
- class ConcreteProduct1 extends Product {
- use() {
- console.log('使用具体产品1');
- }
- }
-
- // 具体产品类2
- class ConcreteProduct2 extends Product {
- use() {
- console.log('使用具体产品2');
- }
- }
-
- // 抽象工厂类
- class Factory {
- // 工厂方法,由子类实现具体的创建逻辑
- createProduct() {
- throw new Error('Use abstract method "createProduct"');
- }
- }
-
- // 具体工厂类1
- class ConcreteFactory1 extends Factory {
- createProduct() {
- return new ConcreteProduct1();
- }
- }
-
- // 具体工厂类2
- class ConcreteFactory2 extends Factory {
- createProduct() {
- return new ConcreteProduct2();
- }
- }
-
- // Client代码
- class Client {
- constructor(factory) {
- this.factory = factory;
- }
-
- useProduct() {
- let product = this.factory.createProduct();
- product.use();
- }
- }
-
- // 使用Client类和ConcreteFactory1实例化一个新的Client对象并使用产品
- let client1 = new Client(new ConcreteFactory1());
- client1.useProduct();
以下是在C++中实现工厂方法模式:
- //定义一个抽象产品类,它包含产品对象的公共接口。
- class Product {
- public:
- virtual void use() = 0; // 纯虚函数,具体实现由子类来决定
- };
- //创建具体产品类,它们扩展了抽象产品类并实现了产品的具体行为。
- class ConcreteProduct1 : public Product {
- public:
- void use() override {
- // 具体实现逻辑
- std::cout << "使用具体产品1" << std::endl;
- }
- };
-
- class ConcreteProduct2 : public Product {
- public:
- void use() override {
- // 具体实现逻辑
- std::cout << "使用具体产品2" << std::endl;
- }
- };
- //定义一个抽象工厂类,它包含一个工厂方法用于创建产品对象。这个方法是纯虚函数,具体实现由子类来决定。
- class Factory {
- public:
- virtual Product* createProduct() = 0; // 纯虚函数,具体实现由子类来决定
- };
- //创建具体工厂类,它们扩展了抽象工厂类并实现了工厂方法的特定实现,以创建特定类型的产品对象。
- class ConcreteFactory1 : public Factory {
- public:
- Product* createProduct() override {
- return new ConcreteProduct1();
- }
- };
-
- class ConcreteFactory2 : public Factory {
- public:
- Product* createProduct() override {
- return new ConcreteProduct2();
- }
- };
- //最后,在客户端代码中使用工厂方法模式来创建产品对象。客户端通过调用工厂对象的 createProduct 方法来创建产品对象,而不需要直接了解如何创建这些对象。这样可以提高客户端代码的灵活性和可维护性。
- int main() {
- Factory* factory = new ConcreteFactory1(); // 创建具体工厂对象
- Product* product = factory->createProduct(); // 创建具体产品对象
- product->use(); // 使用具体产品对象
-
- delete factory; // 释放工厂对象内存
- delete product; // 释放产品对象内存
-
- return 0;
- }
以下是在python中实现工厂方法模式:
- from abc import ABCMeta, abstractmethod
-
- # 抽象产品类
- class Product(metaclass=ABCMeta):
- @abstractmethod
- def operation(self):
- pass
-
- # 具体产品类1
- class ConcreteProduct1(Product):
- def operation(self):
- print("具体产品1被使用了")
-
- # 具体产品类2
- class ConcreteProduct2(Product):
- def operation(self):
- print("具体产品2被使用了")
-
- # 抽象工厂类
- class Factory(metaclass=ABCMeta):
- @abstractmethod
- def create_product(self):
- pass
-
- # 具体工厂类1
- class ConcreteFactory1(Factory):
- def create_product(self):
- return ConcreteProduct1()
-
- # 具体工厂类2
- class ConcreteFactory2(Factory):
- def create_product(self):
- return ConcreteProduct2()
-
- # Client代码
- if __name__ == "__main__":
- factory1 = ConcreteFactory1()
- product1 = factory1.create_product()
- product1.operation()
-
- factory2 = ConcreteFactory2()
- product2 = factory2.create_product()
- product2.operation()
以下是一个示例,展示了如何在go中实现工厂方法模式:
- //首先定义一个产品接口,该接口定义了产品的通用方法:
- type Product interface {
- Use()
- }
- //然后,定义两个具体产品结构体,并实现Product接口的方法:
- type ConcreteProduct1 struct{}
-
- func (p *ConcreteProduct1) Use() {
- fmt.Println("使用具体产品1")
- }
-
- type ConcreteProduct2 struct{}
-
- func (p *ConcreteProduct2) Use() {
- fmt.Println("使用具体产品2")
- }
- //接下来,定义一个工厂接口,该接口定义了一个创建产品的 方法:
- type Factory interface {
- CreateProduct() Product
- }
- //然后,定义两个具体工厂结构体,并实现Factory接口的方法:
- type ConcreteFactory1 struct{}
-
- func (f *ConcreteFactory1) CreateProduct() Product {
- return &ConcreteProduct1{}
- }
-
- type ConcreteFactory2 struct{}
-
- func (f *ConcreteFactory2) CreateProduct() Product {
- return &ConcreteProduct2{}
- }
- //最后,在客户端代码中,根据需要选择具体的工厂结构体实例化,然后使用该工厂结构体创建并使用产品:
- func main() {
- factory1 := &ConcreteFactory1{}
- product1 := factory1.CreateProduct()
- product1.Use()
-
- factory2 := &ConcreteFactory2{}
- product2 := factory2.CreateProduct()
- product2.Use()
- }
以下是一个示例,展示了如何在PHP中实现工厂方法模式:
- //定义一个抽象产品接口(Abstract Product):
- interface Product {
- public function operation();
- }
- //创建具体产品类实现抽象产品接口:
- class ConcreteProduct1 implements Product {
- public function operation() {
- echo "具体产品1被使用了";
- }
- }
-
- class ConcreteProduct2 implements Product {
- public function operation() {
- echo "具体产品2被使用了";
- }
- }
- //定义一个抽象工厂类:
- abstract class Creator {
- abstract public function factoryMethod(): Product;
- }
- //创建具体工厂类继承抽象工厂类:
- class ConcreteCreator1 extends Creator {
- public function factoryMethod() {
- return new ConcreteProduct1();
- }
- }
-
- class ConcreteCreator2 extends Creator {
- public function factoryMethod() {
- return new ConcreteProduct2();
- }
- }
- //在客户端代码中,根据需要选择具体的工厂类实例化,并使用该工厂类创建并使用产品:
- $creator1 = new ConcreteCreator1();
- $product1 = $creator1->factoryMethod();
- $product1->operation(); // 输出:具体产品1被使用了
-
- $creator2 = new ConcreteCreator2();
- $product2 = $creator2->factoryMethod();
- $product2->operation(); // 输出:具体产品2被使用了
《完结》
上一篇《简单工厂模式》 下一篇《抽象工厂模式》