什么是工厂模式
相较于简单工厂,工厂模式最主要的改变在于多了抽象工厂的概念。
为什么要这么做呢?让我们想一下:在简单工厂模式中,如果我们需要新的产品,工厂内部也需要进行改动以附和用户需求,在产品种类繁多的情况下,代码臃肿,耦合程度过高。
工厂模式属于类的创建型模式,关键在于创建产品对象接口,而将实际创建工作发放到子类中,便于分功能开发。工厂模式的核心是一个抽象工厂类,而简单工厂的核心是一个实体类。
在工厂模式里,当系统需要增加产品对象(系列)时,仅仅需要增加这个对象(系列)和对应工厂实体,而不用修改抽象工厂本身,原有的工厂也不需要修改,极大程度上降低了客户端的修改,很好的符合了“开放-封闭”原则。
它有两个突出的优点:
- 需求改变时改动量小
- 具体创建过程与客户端分离
实现步骤
- 提供一个抽象工厂类:我愿意称之为专门建工厂的建筑局,通过它来实例化具体工厂。
- 实例化和产品对应的工厂类:即建筑局建工厂。
- 提供与产品相关的抽象产品类:工厂买生产原料。
- 提供一个或一系列产品:工厂用原料生产产品。
代码与解析
以现实工业为例子,首先有自然界原材料、成立对应的建设局,建设工厂,最后生产产品。因此,在最开始,我们要从抽象产品下手。
//原材料:抽象产品,在这种模式中原材料只有一种类型
class AbsProduct_Mine { //抽象产品:矿物
public:
virtual ~AbsProduct_Mine() {};
AbsProduct_Mine() {
cout << "挖矿" << endl;
}
virtual void produce() = 0;
};
抽象工厂依赖于抽象产品,因为在他的行为中包含了抽象产品,它所知道的是,要生产产品,具体怎么生产,不知道,生产什么产品,不知道,都交给具体工厂来实现,故返回抽象产品类,声明为纯虚函数。
//建设局:抽象工厂类,只存在一个
class AbsFactory {
public:
virtual ~AbsFactory() {};
virtual AbsProduct_Mine* createProduct() = 0;
};
具体工厂的建立依赖于产品,如果不知道产品形式,工厂也无从下手,所以先声明具体产品,它由抽象产品得到,比如下面由矿物制造了三个产品,形式上高度统一,实现上可以各有纷纭。
//具体产品,分别由自己的原料生产(继承于自己对应的抽象产品)
class ConProduct_Plane:public AbsProduct_Mine {
public:
void produce()override {
cout << "我们用矿物生产了一架飞机" << endl;
}
};
class ConProduct_Tank:public AbsProduct_Mine {
public:
void produce()override {
cout << "我们用矿物生产了一辆坦克" << endl;
}
};
class ConProduct_Computer:public AbsProduct_Mine{
public:
void produce()override {
cout << "我们用矿物制造了一台电脑" << endl;
}
};
最后,产品不能无缘无故产生,需要通过工厂,而工厂需要向建设局请示。
于是具体工厂继承于抽象工厂,一个具体工厂返回一个具体产品,当然,也可以通过类似于简单工厂的传参手法,通过一个接口完成不同产品的生产。
//通过建筑局建工厂,工厂具有生产具体产品功能
//具体工厂继承于抽象工厂,具体工厂重写抽象工厂内置函数完成具体产品类生产
class ConFactory_Plane:public AbsFactory {
public:
AbsProduct_Mine* createProduct() override{
return new ConProduct_Plane;
}
};
class ConFactory_Tank :public AbsFactory {
public:
AbsProduct_Mine* createProduct() override {
return new ConProduct_Tank;
}
};
class ConFactory_Computer :public AbsFactory {
public:
AbsProduct_Mine* createProduct() override {
return new ConProduct_Computer;
}
};
实际上第二种大可不必继承下来,与简单工厂完全一致。
class ConFactory_Mine//:public AbsFactory
{
public:
static AbsProduct_Mine* createProduct(int arg) {
switch (arg)//由于case后面是return,不加break也无妨。
{
case 1:return new ConProduct_Plane;
case 2:return new ConProduct_Tank;
case 3:return new ConProduct_Computer;
default:return nullptr;
}
}
};
调用main函数测试
int main() {
//子类对象对父类指针初始化,因此还需要添加虚析构函数
AbsFactory* af = new ConFactory_Plane;
auto plane = af->createProduct();
plane->produce();
af = new ConFactory_Tank;
auto tank = af->createProduct();
tank->produce();
af = new ConFactory_Computer;
auto com = af->createProduct();
com->produce();
cout << "*********************************" << endl;
ConFactory_Mine::createProduct(1)->produce();
ConFactory_Mine::createProduct(2)->produce();
ConFactory_Mine::createProduct(3)->produce();
return 0;
}
结果如下
好啦,今天的分享就到这里~