此次学习参考LoveLion的工厂三兄弟之抽象工厂模式(三)
概述
抽象工厂模式为创建一组对象提供了一种解决方案。与工厂方法模式相比,抽象工厂模式中的具体工厂不只是创建一种产品,它负责创建一族产品。抽象工厂模式定义如下:
抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。
结构

在抽象工厂模式结构图中包含如下几个角色:
- AbstractFactory(抽象工厂):它声明了一组用于创建一族产品的方法,每一个方法对应一种产品。
- ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
- AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
- ConcreteProduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。
代码实现
我们修改工厂方法模式中的例子,添加car与plane:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
| #include <iostream>
using namespace std;
class Tank { public: virtual const string &type() = 0; };
class Tank56 : public Tank { public: Tank56() : Tank(), mstr_type("Tank56") { }
const string &type() override { cout << mstr_type.data() << endl; return mstr_type; }
private: string mstr_type; };
class Tank96 : public Tank { public: Tank96() : Tank(), mstr_type("Tank96") { } const string &type() override { cout << mstr_type.data() << endl; return mstr_type; }
private: string mstr_type; };
class Car { public: virtual const string &type() = 0; };
class Car56 : public Car { public: Car56() : Car(), mstr_type("Car56") { }
const string &type() override { cout << mstr_type.data() << endl; return mstr_type; }
private: string mstr_type; };
class Car96 : public Car { public: Car96() : Car(), mstr_type("Car96") { } const string &type() override { cout << mstr_type.data() << endl; return mstr_type; }
private: string mstr_type; };
class Plane { public: virtual const string &type() = 0; };
class Plane56 : public Plane { public: Plane56() : Plane(), mstr_type("Plane56") { }
const string &type() override { cout << mstr_type.data() << endl; return mstr_type; }
private: string mstr_type; };
class Plane96 : public Plane { public: Plane96() : Plane(), mstr_type("Plane96") { } const string &type() override { cout << mstr_type.data() << endl; return mstr_type; }
private: string mstr_type; };
class Factory { public: virtual Tank *createTank(){}; virtual Car *createCar(){}; virtual Plane *createPlane(){}; };
class Factory56:public Factory { public: Tank *createTank() { return new Tank56(); }
Car *createCar() { return new Car56(); }
Plane *createPlane() { return new Plane56(); } };
class Factory96:public Factory { public: Tank *createTank() { return new Tank96(); } Car *createCar() { return new Car96(); }
Plane *createPlane() { return new Plane96(); } };
int main() { Factory *factory56 = new Factory56(); Factory *factory96 = new Factory96(); Tank *tank56 = factory56->createTank(); tank56->type(); Car *car56 = factory56->createCar(); car56->type(); Plane *plane56 = factory56->createPlane(); plane56->type(); Tank *tank96 = factory96->createTank(); tank96->type(); Car *car96 = factory96->createCar(); car96->type(); Plane *plane96 = factory96->createPlane(); plane96->type();
delete tank96; tank96 = nullptr; delete car96; car96 = nullptr; delete plane96; plane96 = nullptr; delete tank56; tank56 = nullptr; delete car56; car56 = nullptr; delete plane56; plane56 = nullptr; delete factory56; factory56 = nullptr; delete factory96; factory96 = nullptr;
return 0; }
|
此实例中有两个产品族,每个族下面有三个产品,所以有两个工厂负责创建各族的产品
优缺点
优点
- 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易,所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。
- 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
- 增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点
- 增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则”。
适用场景
- 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是很重要的,用户无须关心对象的创建过程,将对象的创建和使用解耦。
- 系统中有多于一个的产品族,而每次只使用其中某一产品族。可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族。
- 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。同一个产品族中的产品可以是没有任何关系的对象,但是它们都具有一些共同的约束,如同一操作系统下的按钮和文本框,按钮与文本框之间没有直接关系,但它们都是属于某一操作系统的,此时具有一个共同的约束条件:操作系统的类型。
- 产品等级结构稳定,设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。