2 Commits c727328b56 ... 9946c9df9d

Author SHA1 Message Date
  Gogs 9946c9df9d 对附属的测试文件进行一定的修改 2 months ago
  Gogs 60aed91344 同上次,上次提交错误文件了 2 months ago
4 changed files with 217 additions and 3 deletions
  1. 1 1
      .gitignore
  2. 2 0
      CRTP.cpp
  3. 211 0
      factory.cpp
  4. 3 2
      test/buid.sh

+ 1 - 1
.gitignore

@@ -1,6 +1,6 @@
 test/builder
 test/CRTP
-
+test/factory
 
 
 

+ 2 - 0
CRTP.cpp

@@ -1,3 +1,5 @@
+//CRTP是一种cpp中独特的设计模式,也是C++多态(静态)的一种实现方法
+//相比与运行时多态的好处是直接生成机器码,有更好的性能但是灵活性更差,生成的代码体积更大
 #include<iostream>
 
 template<typename T> 

+ 211 - 0
factory.cpp

@@ -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();
+}

+ 3 - 2
test/buid.sh

@@ -2,7 +2,8 @@ rm -rf *
 echo "开始构建"
 g++ -O3 ../CRTP.cpp -o CRTP -std=c++20
 g++ -O3 ../builder.cpp -o builder -std=c++20
-
+g++ -O3 ../factory.cpp  -o factory -std=c++20
 echo "开始运行"
 ./builder
-./CRTP
+./CRTP
+./factory