简单工厂,定义一个类负责创建其他对象类的实例,而被创建的对象类一般都有共同的基类。
一般来说简单工厂如果想创建一个对象类,只需要根据名字进行实例化,工厂就会创建相应的对象类。
特点:简单的对不同类对象的创建进行了一层很薄的封装
#include#include //对象类的基类 class Traffic { public: virtual ~Traffic() {} virtual void Show() = 0; }; //汽车 class CarTraffic : public Traffic { public: void Show() { std::cout << "this is CarTraffic" << std::endl; } }; //自行车 class BicycleTraffic : public Traffic { public: void Show() { std::cout << "this is BicycleTraffic" << std::endl; } }; enum TRAFFIC_TYPE { CAR, BICYCLE, PLANE }; //交通工具生产厂 class TrafficFactory { public: std::shared_ptr TrafficCreate(TRAFFIC_TYPE type) { switch (type) { case CAR: return std::make_shared (); break; case BICYCLE: return std::make_shared (); break; default: return nullptr; break; } } }; int main() { TrafficFactory factory; auto car = factory.TrafficCreate(TRAFFIC_TYPE::CAR); auto bicycle = factory.TrafficCreate(TRAFFIC_TYPE::BICYCLE); auto plane = factory.TrafficCreate(TRAFFIC_TYPE::PLANE); if (car) { car->Show(); } if (bicycle) { bicycle->Show(); } if (plane) { plane->Show(); } return 0; }
简单工厂的最大问题:
当有新的对象类要加入时,就必须修改工厂类,这与我们写代码的“开闭原则”相违背。所以这时候应运而生了2.0版本的“工厂方法”
工厂方法的组成部分
- 接口工厂类:提供创建具体对象类的接口,由该对象的具体的工厂类实现。
- 对象工厂类:继承于接口工厂类,实现创建对象类的接口。
- 接口对象类:所有要创建对象都需要拥有的方法基类。
- 对象实体类:继承接口对象类,并要实现对应的方法,对应的工厂将会实例化该对象
#include#include //===================================================================// //对象类的基类 class Traffic { public: virtual ~Traffic() {} virtual void Show() = 0; }; //汽车 class CarTraffic : public Traffic { public: void Show() { std::cout << "this is CarTraffic" << std::endl; } }; //自行车 class BicycleTraffic : public Traffic { public: void Show() { std::cout << "this is BicycleTraffic" << std::endl; } }; //飞机 class PlaneTraffic : public Traffic { public: void Show() { std::cout << "this is PlaneTraffic" << std::endl; } }; //===================================================================// //工厂类的基类 class Factory { public: virtual ~Factory() {} virtual std::shared_ptr TrafficCreate() = 0; }; //汽车工厂 class CarFactory : public Factory { public: std::shared_ptr TrafficCreate() { return std::make_shared (); } }; //自行车 class BicycleFactory : public Factory { public: std::shared_ptr TrafficCreate() { return std::make_shared (); } }; //飞机 class PlaneFactory : public Factory { public: std::shared_ptr TrafficCreate() { return std::make_shared (); } }; //===================================================================// int main() { { auto factory = std::make_shared (); auto traffic = factory->TrafficCreate(); traffic->Show(); } { auto factory = std::make_shared (); auto traffic = factory->TrafficCreate(); traffic->Show(); } { auto factory = std::make_shared (); auto traffic = factory->TrafficCreate(); traffic->Show(); } return 0; }
工厂方法的优劣
优势:
- 当需要增加一个新的对象类时,无需修改原有的工厂类及对象类
- 职责单一,每个工厂负责维护自己的产品(对象)类
缺点:
- 当需要增加一个或多个产品(对象)时,需要创建一一对应的工厂,一下子变得又繁琐起来
- 当对象类的基类要增加某一个公用方法时,所有的产品类都需要修改。
这时当我们有不同交通工具配件需要生产怎么办?这时候可以把简单工厂与工厂方法进行整合实现抽象工厂模式(3.0)
抽象工厂假设我们这时小汽车厂要同时生产小汽车的轮胎,那么我们只需要对工厂进行扩充方法,来实现一个工厂来生产不同的产品
#include简单工厂、工厂方法与抽象工厂的理解#include //===================================================================// //对象类的基类 class Traffic { public: virtual ~Traffic() {} virtual void Show() = 0; }; //交通工具轮胎 class TrafficTyre { public: virtual void TyreName() = 0; virtual ~TrafficTyre() {} }; //汽车 class CarTraffic : public Traffic { public: void Show() { std::cout << "this is CarTraffic" << std::endl; } }; //汽车轮胎 class CarTyre : public TrafficTyre { public: void TyreName() { std::cout << "this is CarTyre" << std::endl; } }; //===================================================================// //工厂类的基类 class Factory { public: virtual ~Factory() {} virtual std::shared_ptr TrafficCreate() = 0; virtual std::shared_ptr TyreCreate() = 0; }; //汽车工厂 class CarFactory : public Factory { public: std::shared_ptr TrafficCreate() { return std::make_shared (); } std::shared_ptr TyreCreate() { return std::make_shared (); } }; //===================================================================// int main() { auto factory = std::make_shared (); auto traffic = factory->TrafficCreate(); auto tyre = factory->TyreCreate(); tyre->TyreName(); traffic->Show(); return 0; }
工厂方法:适用于结构比较唯一的场景,为同一类的产品提供创建的接口,比如只区分汽车和飞机,自行车。
抽象工厂:适用与同一级结构比较复杂的场景,比如汽车工厂同时要生产不同型号高中低档的车。
简单工厂:更适用快速的把产品与工厂进行解耦。
个人体验:简单工厂和工厂方法用的较多。而抽象工厂更像是把一类东西划成一族时时使用,自己几乎很少在工程中使用。
参考连接



