简单工厂、工厂方法、抽象工厂
简单工厂、工厂方法、抽象工厂
属于创建型设计模式
简单工厂(Simple Factory)
简单工厂(Simple Factory) 不属于标准的OOP设计模式中的一项,工厂方法和抽象工厂是属于标准的23种设计模式的;
在编写大型C++软件的时候,代码里面会出现,每次创建对象的时候,都需要通过new 类名称的方式来生成对象,这样一来,用户,暂且不管记不记得住,这样的设计使得代码很难维护,,不符合我们软件设计的思想,Simple Factory就是在这样的需求下诞生的。
工厂方法主要是封装了对象的创建!
1.1、采用new的方式创建对象
class Car {
public:
Car(string name) : _name(name) {}
virtual void show() = 0;
protected:
string _name;
};
class Bmw : public Car {
public:
Bmw(string name) : Car(name) {}
void show() {
cout << "获取了一辆宝马汽车:" << _name << endl;
}
};
class Audi : public Car {
public:
Audi(string name) : Car(name) {}
void show() {
cout << "获取了一辆奥迪汽车:" << _name << endl;
}
};
int main() {
Car *p1 = new Bmw("X1");
Car *p2 = new Audi("A6");
}
缺点:
1.2、采用简单工厂

- 从上面的UML类图可以看出,所有对象的创建不再通过new 类名称的方式进行了,而是把对象的创建都封装在了SimpleFactory类的createProduct方法当中;
- 通过传入一个事先设计好的枚举类型,然后返回一个对应的对象,既解耦了对象的创建,还不用再记忆那么多的类名。
实现
将类名设为首字母大写:(防止和枚举的名称重复)
class Bmw : public Car {
public:
Bmw(string name) : Car(name) {}
void show() {
cout << "获取了一辆宝马汽车:" << _name << endl;
}
};
class Audi : public Car {
public:
Audi(string name) : Car(name) {}
void show() {
cout << "获取了一辆奥迪汽车:" << _name << endl;
}
};
enum CarType {
BMW, AUDI
};
class SimpleFactory {
public:
Car* createCar(CarType ct) {
switch(ct) {
case BMW:
return new Bmw("X1");
case AUDI:
return new Audi("A6");
default:
cerr << "传入工厂的参数不正确" << ct << endkl;
break;
}
return nullptr;
}
};
int main() {
//Car* p1 = new Bmw("X1");
//Car* p2 = new Audi("A6");
SimpleFactory * factory = new SimpleFactory();
Car* p1 = factory->createCar(BMW);
Car* p2 = factory->createCar(AUDI);
p1->show();
p2->show();
delete p1;
delete p2;
delete p3;
return 0;
}
也可以在工厂方法中使用管理:
#include <memory>
int main() {
unique_ptr<SimpleFactory> factory(new SimpleFactory());
unique_ptr<Car> p1(factory->createCar(BMW));
unique_ptr<Car> p2(factory->createCar(AUDI));
p1->show();
p2->show();
return 0;
}
缺点:把所有对象的创建都封装在了一个SimpleFactory类的createCar函数中,根据传入的参数,选择产生不同的对象,很明显,,所以这样的设计不能算完美。
2、工厂方法(Factory Method)
2.1、类图
Factory Method工厂方法是标准的OOP设计模式之一,主要解决了上面使用简单工厂遇到的问题。
工厂方法为每一种产品提供相应的实例工厂进行对象创建,更符合实际的面向对象设计,比如说不同厂家的汽车,肯定都有自己的汽车生产工厂,BMW和Audi两种汽车都有自己的工厂在生产。
先看看工厂方法的UML类设计图如下:

class Factory {
public:
virtual Car* createCar(string name) = 0;
};
class BMWFactory : public Factory {
public:
Car* createCar(string name) {
return new Bmw(name);
}
};
class AudiFactory : public Factory {
public:
car* createCar(string name) {
return new Audi(name);
}
};
int main() {
unique_ptr<Facory> bmwfty(new BMWFactroy());
unique_ptr<Facory> audifty(new AudiFactroy());
unique_ptr<Car> p1(bmwfty->createCar("X6"));
unique_ptr<Car> p2(audifty->createCar("A8"));
p1->show();
p2->show();
return 0;
}
优点:符合软件设计的开-闭原则;
缺点:
就是每一个实例工厂负责生产一个实例产品,也就是,那么小米不仅仅生产手机,还生产耳机,智能手环,智能插座等等相关的小米产品簇;
- ,而且也不符合实际情况。
实际上小米或者华为的工厂里面,有相关联的产品簇都是在一个工厂完成创建的;BMW或者Audi汽车制造工厂除了生产汽车,生产线上也有可能生产轮胎,或者其它的汽车附属产品。
所以对于包含产品簇这么一类实体关系的设计,就需要使用Abstract Factory抽象工厂了,你也可以把上面的工厂方法看作只生产一种产品的抽象工厂,本质是相同的。
抽象工厂(Abstract Factory)
抽象工厂其实就是解决设计的

- 看上面抽象工厂的UML类设计图,ProductA和ProductB就是一个产品簇。
//系列产品1
class Car {
public:
Car(string name) : _name(name) {}
virtual void show() = 0;
protected:
string _name;
};
class Bmw : public Car {
public:
Bmw(string name) _name(name) {}
void show() {
cout << "获取了一辆宝马汽车:" << _name << endl;
}
};
class Audi : public Car {
public:
Audi(string name) : Car(name) {}
void show() {
cout << "获取了一辆奥迪汽车:" << _name << endl;
}
};
//系列产品2
class Light {
public:
virtual void show() = 0;
};
class BmwLight : public Light {
public:
void show() {
cout << "BMW Light!" << endl;
}
};
class AudiLight : public Light {
void show() {
cout << "Audi Light!" << endl;
}
};
此时创建宝马对象时,因为有产品簇,不可能说又来一个宝马灯工厂,来创建宝马灯,这样的话各种配件,导致工厂类太多了!
将工厂方法写成抽象工厂!
//工厂方法 =》抽象工厂(对有一组关联关系的产品簇提供产品对象的同一创建)
class AbstractFactory {
public:
virtual Car* createCar(string name) = 0;//工厂方法 创建汽车
virtual Light* createCarLight() = 0;//工厂方法 创建汽车关联的产品
}
//把有关联的产品放在一个工厂中,提供多个产品创建的抽象接口!
class BMWFactory : public AbstractFactory {
public:
Car* createCar(string name) {
return new Bmw(name);
}
Light* createCarLight() {
return new BmwLight();
}
};
class AudiFactory : public AbstractFactory {
public:
Car* createCar(string name) {
return new Audi(name);
}
Light* createCarLight() {
return new AudiCarLight();
}
};
int main() {
//现在考虑产品 一类产品(有关联关系的系列产品)
unique_ptr<AbstractFactory> bmwfty(new BMWFactory());
unique_ptr<AbstractFactory> audifty(new AudiFactory());
unique_ptr<Car> p1(bmwfty->createCar("X6"));
unique_ptr<Car> p2(audifty->createCar("A8"));
unique_ptr<Light> l1(bmdfty->createCarLight());
unique_ptr<light> l2(auditfy->createCarLight());
p1->show();
l1->show();
p2->show();
l2->show();
return 0;
}
优点:使得,不用每个产品类建一个工厂
缺点:(抽象类必须重写!)!!!
简单工厂,工厂方法,抽象工厂对比
