1. 工厂模式的概念
工厂模式的实际操作效果和其名字一样,并非是通过直接创建对象的方式来实现,其主要依靠于工厂这个创建体来实现对象的创建。具体情况下,其分为简单工厂模式,工厂模式以及抽象工厂模式。
2. 不同工厂模式的区别与实现
2.1 简单工厂模式
简单工厂模式即为静态工厂模式,其并不属于标准的23种设计模式之一。具体是通过创建所有对象的父类,而该父类负责描述所有实例所共有的公共接口,具体的类图可以大概表示如下:
可见其整体构造方式较为简单,单纯的为工厂创建出不同的产品而已。从通俗的理解上来讲,这种简单的工厂模式就是一个工厂中设计了多种生产线生产不同的产品,而这些产品都是参考一个模板(抽象角色)来形成的。每当想要生产一个产品时,就去使用对应的生产线(调用对应的create函数)即可。
但是其问题可以说也很明显,当我想要制造一个新产品时,我就需要再增加一条流水线(create函数),而当我不需要制造某个产品时,这个流水线就只能闲置,即使是制作相似的两个产品,也只能增加流水线。可见这种工厂的代码会随着产品的代码改变而改变的设计模式,是难以大规模使用的。
其具体的实现与测试代码如下所示:
#include <iostream>
using namespace std;
class color
{
public:
virtual void mycolor() {}
};
class blue : public color
{
public:
void mycolor() { cout << "blue" << endl; }
};
class red : public color
{
public:
void mycolor() { cout << "red" << endl; }
};
class green : public color
{
public:
void mycolor() { cout << "green" << endl; }
};
class factory
{
public:
color* create(string c)
{
if (c == "blue")
return new blue;
else if (c == "red")
return new red;
else if (c == "green")
return new green;
else
cout << "error input" << endl;
}
};
int main_simplyFactory()
{
factory *f = new factory;
color* r = f->create("red");
r->mycolor();
color* b = f->create("blue");
b->mycolor();
color* g = f->create("green");
g->mycolor();
delete r, b, g;
delete f;
return 0;
}
2.2 工厂模式
工厂模式就是最普通,最基本的工厂模式了,其主要面对抽象的工厂去编程,从而实现无数个工厂,每当需要制作什么产品/新产品,就使用对应的工厂去生产东西,其具体的类图可以表述如下:
工厂模式的主要操作,就是首先定义抽象角色和抽象工厂,然后在每当需要新产品时,就调用抽象角色来创建新的产品。而抽象工厂则在其内部定义了返回抽象角色的创建函数create,其他所有的具体工厂均将继承抽象工厂来实例化对应的create函数。通俗一点来说,抽象工厂就是督导部门,具体工厂就是加工单位,加工单位通过督导部门得到生产的要领,然后自己来生产新的产品,但是这些产品都是来自于督导所规定的产品之内(即必须要属于抽象角色)。每当有新的产品需要生产时,只需要参照督导部门继承一个新的工厂,重载create为新的产品的制作即可,而不需要去改变别的工厂/抽象工厂的代码。
这样的模式仍然也有一个问题,那就是每个对应的工厂都只制造一个产品,而无法针对产品的多样化进行灵活变通,比如当需要制作一个8mm的螺丝和10mm的螺丝时,可能使用工厂模式还是需要建立两个工厂来实现的,但是实际情况下都是希望一家工厂实现相关的所有的产品的制作,比如螺丝。
此模式的实现代码如下:
#include <iostream>
using namespace std;
class color
{
public:
virtual void mycolor() {}
};
class blue : public color
{
public:
void mycolor() { cout << "blue" << endl; }
};
class red : public color
{
public:
void mycolor() { cout << "red" << endl; }
};
class ABfactory
{
public:
virtual color* create() { return NULL; }
};
class RedFactory : public ABfactory
{
public:
color* create()
{
return new red;
}
};
class BlueFactory : public ABfactory
{
public:
color* create()
{
return new blue;
}
};
int main_Factory()
{
ABfactory *abf;
abf = new BlueFactory;
color* b = abf->create();
b->mycolor();
delete abf, b;
abf = new RedFactory;
color* r = abf->create();
r->mycolor();
delete abf, r;
return 0;
}
2.3 抽象工厂模式
其与工厂模式最大的区别,就是一个工厂其可以生产一整个产品线(内部有很多产品组成),其具体的类图构成如下所示:
抽象工厂模式可以说是工厂模式中的最为集成者了。其首先仍然需要创建抽象角色与抽象工厂,但此时的抽象工厂并不只单单的制造一种产品,而是对应不同的抽象产品种类,来建立不同虚函数create。由此,通过抽象工厂所实例化的具体工厂,也就具备了抽象工厂所能create的所有产品,而根据不同工厂实例化的不同,就可以生产同种类型,但性质不同的具体产品了。每当需要添加新产品时,在抽象工厂类进行create的添加,然后各个具体工厂接着进行继承学习,从而实现整体的工厂模式。
其最大的优势在于,对于新产品的添加,无需更改其原有的其他产品的构造方式,并根据不同工厂的性质不同,生产出不同性质但类别相同的产品(即开闭原则)。但同时,其问题也就是对于产品线的增加过程需要修改抽象工厂—修改具体工厂这个过程,较为繁琐,在对应大量产品线并没有那么适用。具体实现代码如下:
#include <iostream>
using namespace std;
class AbFruit
{
public:
virtual void myname() {}
};
class AbFactory
{
public:
virtual AbFruit* createBanana() = 0;
virtual AbFruit* createApple() = 0;
};
class SouthBanana : public AbFruit
{
void myname()
{
cout << "南方香蕉" << endl;
}
};
class SouthApple : public AbFruit
{
void myname()
{
cout << "南方苹果" << endl;
}
};
class NorthBanana : public AbFruit
{
void myname()
{
cout << "北方香蕉" << endl;
}
};
class NorthApple : public AbFruit
{
void myname()
{
cout << "北方苹果" << endl;
}
};
class SouthFactory : public AbFactory
{
public:
AbFruit* createBanana()
{
cout << "生成南方的香蕉" << endl;
return new SouthBanana;
}
AbFruit* createApple()
{
cout << "生成南方的苹果" << endl;
return new SouthApple;
}
};
class NorthFactory : public AbFactory
{
public:
AbFruit* createBanana()
{
cout << "生成北方的香蕉" << endl;
return new NorthBanana;
}
AbFruit* createApple()
{
cout << "生成北方的苹果" << endl;
return new NorthApple;
}
};
int main()
{
AbFruit* fruit;
SouthFactory* southfa = new SouthFactory;
NorthFactory* northfa = new NorthFactory;
fruit = southfa->createApple();
fruit->myname();
delete fruit;
fruit = southfa->createBanana();
fruit->myname();
delete fruit;
fruit = northfa->createBanana();
fruit->myname();
delete fruit;
fruit = northfa->createApple();
fruit->myname();
delete fruit;
}