|
@@ -0,0 +1,211 @@
|
|
|
+//工厂方法,类工厂以及抽象工厂(和构造器模式有一些重叠)
|
|
|
+//工厂的核心是对类的构建
|
|
|
+#include<memory>
|
|
|
+#include<iostream>
|
|
|
+#include<map>
|
|
|
+//从基本的类开始
|
|
|
+//给一个类设计一个工厂方法
|
|
|
+//工厂方法的好处是可以直接强制对外要求生成的类的封装格式(如智能指针,json数据流等)
|
|
|
+class basic_factory
|
|
|
+{
|
|
|
+private:
|
|
|
+ int data;
|
|
|
+protected:
|
|
|
+ basic_factory(){}
|
|
|
+public:
|
|
|
+ static std::shared_ptr<basic_factory> create() //一个简单的工厂方法,只能通过工厂方法构建(这样可以强制要求只能获取智能指针中的对象)
|
|
|
+ {
|
|
|
+ return std::shared_ptr<basic_factory>(new basic_factory);
|
|
|
+ }
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+//类工厂(简单版本)
|
|
|
+//将所有类的的构造函数全部设置为protected,将工厂类设置为对应类的友元(即一种侵入式的构建方式,必须在设计的时候就做好,否则很难修改)
|
|
|
+
|
|
|
+class factory;
|
|
|
+class A
|
|
|
+{
|
|
|
+ int data;
|
|
|
+ friend factory;
|
|
|
+protected:
|
|
|
+ A(){}
|
|
|
+};
|
|
|
+
|
|
|
+class B
|
|
|
+{
|
|
|
+ int data;
|
|
|
+ friend factory;
|
|
|
+protected:
|
|
|
+ B(){}
|
|
|
+};
|
|
|
+
|
|
|
+//当然由于只有工厂能创建对象(产品)那么实际上工厂还可以负责售后(因为工厂有所有的类的信息),即保存每一个数据指针,最后一次性释放空间
|
|
|
+class factory
|
|
|
+{
|
|
|
+public:
|
|
|
+ static std::shared_ptr<A> create_A()
|
|
|
+ {
|
|
|
+ return std::shared_ptr<A>(new A);
|
|
|
+ }
|
|
|
+ static std::shared_ptr<B> create_B()
|
|
|
+ {
|
|
|
+ return std::shared_ptr<B>(new B);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+//工厂方法与多态
|
|
|
+class base
|
|
|
+{
|
|
|
+public:
|
|
|
+ virtual void print()
|
|
|
+ {
|
|
|
+ std::cout<<"basic"<<std::endl;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+class base_A:public base
|
|
|
+{
|
|
|
+public:
|
|
|
+ void print()override
|
|
|
+ {
|
|
|
+ std::cout<<"A"<<std::endl;
|
|
|
+ }
|
|
|
+};
|
|
|
+class base_B:public base
|
|
|
+{
|
|
|
+public:
|
|
|
+ void print()override
|
|
|
+ {
|
|
|
+ std::cout<<"B"<<std::endl;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+class factory_V
|
|
|
+{
|
|
|
+public:
|
|
|
+
|
|
|
+ static std::shared_ptr<base> create(int type)
|
|
|
+ {
|
|
|
+ switch(type)
|
|
|
+ {
|
|
|
+ case 1:
|
|
|
+ {
|
|
|
+ return std::shared_ptr<base>(new base);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case 2:
|
|
|
+ {
|
|
|
+ return std::shared_ptr<base>(new base_A);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case 3:
|
|
|
+ {
|
|
|
+ return std::shared_ptr<base>(new base_B);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ return std::shared_ptr<base>(new base);
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+//嵌套工厂(在类内定义工厂)直接将类和工厂绑定
|
|
|
+class insert
|
|
|
+{
|
|
|
+ int data;
|
|
|
+ class factory
|
|
|
+ {
|
|
|
+ protected:
|
|
|
+ factory()=default;
|
|
|
+ public:
|
|
|
+ std::shared_ptr<insert> create()
|
|
|
+ {
|
|
|
+ return std::move(std::shared_ptr<insert>(new insert));
|
|
|
+ }
|
|
|
+ };
|
|
|
+public:
|
|
|
+ static factory lab;
|
|
|
+};
|
|
|
+
|
|
|
+//抽象工厂
|
|
|
+//抽象工厂设计模式是一种高度复杂的设计模式
|
|
|
+//抽象工厂的名称来源是当有大量相似的物体需要不同的工厂,会设计一个抽象类(抽象工厂作为接口),其余的工厂从这个抽象工厂中继承
|
|
|
+//当然最后为了不使用这么大量的工厂,还会在使用一个工厂对所有的构造工厂进行封装
|
|
|
+//总感觉带点过度设计的意思
|
|
|
+
|
|
|
+//有两种饮料,要分别准备
|
|
|
+class prepare_coffee;
|
|
|
+class prepare_water;
|
|
|
+struct drink
|
|
|
+{
|
|
|
+
|
|
|
+};
|
|
|
+struct coffee:public drink
|
|
|
+{
|
|
|
+ int c;
|
|
|
+private:
|
|
|
+ coffee()=default;
|
|
|
+ friend prepare_coffee;
|
|
|
+};
|
|
|
+struct water:public drink
|
|
|
+{
|
|
|
+ int c;
|
|
|
+private:
|
|
|
+ water()=default;
|
|
|
+ friend prepare_water;
|
|
|
+};
|
|
|
+
|
|
|
+class abstract //抽象工厂
|
|
|
+{
|
|
|
+public:
|
|
|
+ virtual std::shared_ptr<drink> prepare()=0;
|
|
|
+};
|
|
|
+
|
|
|
+class prepare_water:public abstract
|
|
|
+{
|
|
|
+public:
|
|
|
+ std::shared_ptr<drink> prepare()override
|
|
|
+ {
|
|
|
+ return std::move(std::shared_ptr<drink>(new water));
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+class prepare_coffee:public abstract
|
|
|
+{
|
|
|
+public:
|
|
|
+ std::shared_ptr<drink> prepare()override
|
|
|
+ {
|
|
|
+ return std::move(std::shared_ptr<drink>(new coffee));
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+//当然如果用工厂群太抽象了
|
|
|
+class prepare_drink
|
|
|
+{
|
|
|
+private:
|
|
|
+ std::map<std::string,std::shared_ptr<abstract>> prepare_drinks;
|
|
|
+public:
|
|
|
+ prepare_drink()
|
|
|
+ {
|
|
|
+ prepare_drinks["coffee"]=std::make_shared<prepare_coffee>();
|
|
|
+ prepare_drinks["water"]=std::make_shared<prepare_water>();
|
|
|
+ }
|
|
|
+ std::shared_ptr<drink> prepare(const std::string& name)
|
|
|
+ {
|
|
|
+ std::shared_ptr<drink> result=prepare_drinks[name]->prepare();
|
|
|
+ return std::move(result);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+int main()
|
|
|
+{
|
|
|
+ basic_factory::create();
|
|
|
+
|
|
|
+ factory_V::create(1)->print();
|
|
|
+ factory_V::create(2)->print();
|
|
|
+ factory_V::create(3)->print();
|
|
|
+
|
|
|
+ insert::lab.create();
|
|
|
+}
|