工厂方法模式定义一个创建对象的接口,让子类决定实例化那个类,也就是让类的实例化推迟到子类中进行。因为当需要增加一个新的产品时,我们需要增加一个具体的产品类和与之对应的具体子工厂,然后在具体子工厂方法中进行对象实例化,所以称为工厂方法模式。这个模式非常符合“开闭原则”,当需要增加一个新的产品时,我们只需要增加一个具体的产品类和与之对应的具体工厂即可,无须修改原有系统。同时在工厂方法模式中用户只需要知道生产产品的具体工厂即可,无须关系产品的创建过程,甚至连具体的产品类名称都不需要知道。
1.示例代码
//工厂方法模式工厂代码
#include <iostream>
using namespace std;
//抽象产品
class AbstractProduct {
public:
virtual ~AbstractProduct() {}
virtual void Operation() = 0;
};
//具体产品
class ProductA : public AbstractProduct {
public:
void Operation() {
cout << "ProductA" << endl;
}
};
//具体产品B
class ProductB : public AbstractProduct {
public:
void Operation() {
cout << "ProductB" << endl;
}
};
//抽象工厂
class AbstractFactory {
public:
virtual AbstractProduct* CreateProduct() = 0;
virtual ~AbstractFactory() {}
};
//具体工厂1:生产产品A1和B1
class ConcreteFactoryA : public AbstractFactory {
public:
AbstractProduct* CreateProduct() {
return new ProductA();
}
};
//具体工厂2:生产产品A2和B2
class ConcreteFactoryB : public AbstractFactory {
public:
ProductB* CreateProduct() {
return new ProductB();
}
};
int main()
{
AbstractFactory* factoryA = new ConcreteFactoryA();
AbstractProduct* productA = factoryA->CreateProduct();
productA->Operation();
AbstractFactory* factoryB = new ConcreteFactoryB();
AbstractProduct* productB = factoryB->CreateProduct();
productB->Operation();
delete factoryA;
delete productA;
delete factoryB;
delete productB;
return 0;
}
2. 组成结构
看过上一篇“简答工厂模式”的同学都知道,我们的逻辑是从核心函数入手,这里我们不再赘述,核心的业务函数依旧是Operation()。围绕这个核心函数,我们来看看工厂方法模式使用哪些组角色。
工厂方法模式包含的4个角色:
- Product(抽象产品):它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的父类。
- ConcreteProduct(具体产品):它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品之间一一对应。
- Factroy(抽象工厂):在抽象工厂类中声明了工厂方法(Factory method),用于返回一个产品。抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。
- ConcreteFactory(具体工厂):它是抽象工厂类的子类,实现了在抽象工厂中声明的工厂方法,并可由客户端调用,返回一个具体产品类的实例。
3.简单工厂与工厂方法的对比
事项 | 简单工厂 模式 | 工厂方法 模式 | 说明 |
抽象 工厂 | 无抽象工厂 | 有抽象工厂 | 1.由于简单工厂模式没有抽象工厂,因此当增加新的产品需要修改工厂类的判断逻辑,违背开闭原则。 2.工厂方法模式抽象出了工厂类,并把具体产品对象的创建放到具体工厂类实现。实现了一个工厂生产一类产品,不需要修改工厂类,只需要增加新的具体工厂类即可增加产品。 |
实例化 | 简单工厂类负责实例化 | 具体工厂类负责实例化 | 1.简单工厂模式将产品的实例化职责交给简单工厂的静态方法,注意这里是静态方法,而不是对象。 2.工厂方法模式是通过子类实例化产品。 |
4.优缺点
优点: 工厂方法模式抽象出了工厂类,并把具体产品对象的创建放到具体工厂类实现。实现了一个工厂生产一类产品,不需要修改工厂类,只需要增加新的具体工厂类即可。
缺点: 每新增一个产品,就需要增加一个对应的产品的具体工厂类。相比简单工厂模式而言,工厂方法模式需要更多的类定义。
5.应用场景
- 客户端不知道它所需要的对象的类时,可以使用工厂方法。工厂方法将创建产品的代码与实际使用产品的代码分离,从而能在不影响其他代码的情况下扩展产品创建部分代码。
- 需要向应用中添加一种新产品时,只需要开发新的创建者子类,然后重写其工厂方法即可。
- 用户希望扩展软件库或框架的内部组件时,可以使用工厂方法。可以将各框架中构造组件的代码集中到单个工厂方法中,并在继承该组件之外允许任何人对该方法进行重写。
总之,工厂方法模式适合在无法预知对象确切类别及其依赖关系的情况下使用,同时也可以应用于需要扩展软件库或框架内部组件的场景。
引用:
1.2.5 万字详解:23 种设计模式 - 知乎 (zhihu.com)
2.https://blog.csdn.net/lovely_yoshino/article/details/123138303