工厂模式的主要目的是将具体类的实例化延迟到子类,但是一般的工厂方法模式,如果新增加一种产品,必须先要增加一个相应的工厂类。现在发现可以用c++的模板来实现,新增一种产品不需要新增一个工厂类
/*************************************************************************
> File Name: factory.cpp
> Author: ma6174
> Mail: ma6174@163.com
> Created Time: 2020年05月15日 星期五 22时46分01秒
************************************************************************/
#include<iostream>
using namespace std;
//产品类抽象
class Product
{
public:
Product() = default;
~Product(){}
};
class ConcreteProduct : public Product
{
public:
ConcreteProduct() { cout << "ConcreteProduct constructor" << endl;};
~ConcreteProduct() = default;
ConcreteProduct(const ConcreteProduct& other) = default;
ConcreteProduct& operator = (const ConcreteProduct& other) = default;
};
class ConcreteProduct1 : public Product
{
public:
ConcreteProduct1(){ cout << "ConcreteProduct1 constructor" << endl;}
~ConcreteProduct1() = default;
};
//单例工场,CreateProduct方法返回的是抽象产品的指针,换句话说,只要是Product的子类都能创建
template <class T>
class Factory
{
private:
//单利模式也可以把构造函数设置为protected,这样这个单利类就是可以继承的,如果为私有的就不能有子类
Factory() = default;
public:
~Factory() = default;
Product* CreateProduct(){ return new T;}
static Factory<T>* GetInstance()
{
//c++11有内存屏障,多线程情况下也不会产生多个实例
static Factory<T> ins;
return &ins;
}
};
template <class T>
Product* GetProductFromFactory(Factory<T> *fat)
{
return fat->CreateProduct();
}
int main(int argc, char** argv)
{
GetProductFromFactory(Factory<ConcreteProduct>::GetInstance());
GetProductFromFactory(Factory<ConcreteProduct1>::GetInstance());
return 0;
}
以上工厂模式的最大好处就是新增加一个具体产品的时候,各个接口都不需要修改,只需要新建一个类继承Product接口,然后调用GetProductFromFactory方法就能产生一个新的对象。满足面向对象设计的原则,开闭原则,对扩展开放,对修改封闭。
以前会这样想,先加一个具体的产品对象比如ConcreteProductA, 需要一个产品对象的时候直接 new ConcreteProductA不就好了,何必大费周章的还搞个工厂。现在想想,理由有以下几点:1、如果你在使用一个别人提供的框架, 框架必须要使用你的ConcreteProductA,但是框架怎么知道你这个类,框架代码是固定的,不可能修改让框架再添加一条语句 new ConcreteProductA。如果按照上面的范式,调用框架提供的GetProductFromFactory,那么就能在既不更改框架代码的情况下,框架又能获取到你 的产品对象了。2、开闭原则,我们在新增功能的同时,不能影响到以前的代码,这就要做到对旧代码的改动尽可能的少,甚至做到不改动,这就是面向对象编程要达到的目的。