设计模式 - 创建型

[复制链接]
发表于 2024-10-14 07:02:28 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
创建型

分类缘故起因
创建型设计模式抽象了实例化过程。


  • 它们资助一个体系独立于 一些对象

    • 创建它的对象
    • 组合它的对象
    • 表示它的对象

  • 这些创建型设计模式,有两个不停出现的主旋律。封装该体系内:

    • 使用哪些具体的类
    • 这些类的实例是怎样被创建和被放在一起的。

  • 创建型模式,给予了灵活性

    • 什么被创建,创建了它,它怎么被创建,何时被创建

单例模式,工厂方法模式,抽象工厂模式,建造者模式,原型模式
对象创建Factory 模式被实例化的子类AbstactFactory 模式产物对象家属Prototype 模式针对被实例化的类Builder 模式怎样创建一个组合对象对象创建&对象性能Singleton 模式针对一个类的唯一实例 单例模式

用途

实现单例模式的步骤:
1、构造函数私有化
2、增长静态私有的当前类的指针变量
3、提供静态对外接口,可以让用户获得单例对象
饿汉式

饿汉式:


  • 还没有使用该单例对象,该单例对象就已经被加载到内存了
  • 在对象过多时会造成内存浪费
需要在main函数前,为单例对象赋值。
  1. instance created hungryly.
  2. process started !
  3. waiting done.
  4. got instance
  5. m property is  2
  6. process exit
复制代码
  1. #include <cstdio>
  2. #include <iostream>
  3. #include <thread>
  4. #include <chrono>
  5. using namespace std;
  6. class Singleton_hungry{
  7. private:
  8.     int mProp = 0;
  9.     Singleton_hungry(int intParam = 1):mProp(intParam) {
  10.         printf("instance created hungryly.\n");
  11.     };
  12.     ~Singleton_hungry() {
  13.         if (mInstance) {
  14.             delete mInstance;
  15.         }
  16.         printf("instance deleted.\n");
  17.     }
  18. public:
  19.     static Singleton_hungry* mInstance;
  20.     static Singleton_hungry* getInstance() {
  21.         printf("got instance\n");
  22.         if (mInstance) {
  23.             return mInstance;
  24.         }
  25.         mInstance = new Singleton_hungry;
  26.         return mInstance;
  27.     }
  28.     void do_print() {
  29.         printf("m property is  %d \n", mProp);
  30.     }
  31. };
  32. //以下语句需要在main函数运行前执行
  33. Singleton_hungry* Singleton_hungry::mInstance = new Singleton_hungry(2);
  34. int main() {
  35.     Singleton_hungry* mHungryPtr;
  36.     printf("process started !\n");
  37.     std::this_thread::sleep_for(std::chrono::milliseconds(400));
  38.     printf("waiting done.\n");
  39.     mHungryPtr = Singleton_hungry::getInstance();
  40.     mHungryPtr->do_print();
  41.     std::this_thread::sleep_for(std::chrono::milliseconds(400));
  42.     printf("process exit\n");
  43.     return 1;
  44. }
复制代码
懒汉式

懒汉式:


  • 避免了内存浪费
  • 引入新标题:线程不安全——可以通过互斥量来解决。线程不安全的标题。
  1. #include <cstdio>
  2. #include <iostream>
  3. #include <thread>
  4. #include <chrono>
  5. using namespace std;
  6. class Singleton_hungry{
  7. private:
  8.     int mProp = 0;
  9.     Singleton_hungry(int intParam = 1):mProp(intParam) {
  10.         printf("instance created hungryly.\n");
  11.     };
  12.     ~Singleton_hungry() {
  13.         if (mInstance) {
  14.             delete mInstance;
  15.         }
  16.         printf("instance deleted.\n");
  17.     }
  18. public:
  19.     static Singleton_hungry* mInstance;
  20.     static Singleton_hungry* getInstance() {
  21.         printf("got instance\n");
  22.         if (mInstance) {
  23.             return mInstance;
  24.         }
  25.         mInstance = new Singleton_hungry;
  26.         return mInstance;
  27.     }
  28.     void do_print() {
  29.         printf("m property is  %d \n", mProp);
  30.     }
  31. };
  32. //以下语句需要在main函数运行前执行
  33. Singleton_hungry* Singleton_hungry::mInstance = new Singleton_hungry(2);
  34. int main() {
  35.     Singleton_hungry* mHungryPtr;
  36.     Singleton_hungry* mHungryPtr2;
  37.     printf("process started !\n");
  38.     std::this_thread::sleep_for(std::chrono::milliseconds(400));
  39.     printf("waiting done.\n");
  40.     mHungryPtr = Singleton_hungry::getInstance();
  41.     mHungryPtr2 = Singleton_hungry::getInstance();
  42.     if (mHungryPtr != mHungryPtr2) {
  43.         printf("fail to get instance \n");
  44.     } else {
  45.         printf("get same instance\n");
  46.     }
  47.     std::this_thread::sleep_for(std::chrono::milliseconds(400));
  48.     printf("process exit\n");
  49.     return 1;
  50. }
复制代码
工厂模式

  1. #include <cstdio>
  2. #include <iostream>
  3. using namespace std;
  4. class AbstractProduct {
  5. public:
  6. virtual void do_something() = 0;
  7. };
  8. class ConcreteProductA_1 : public AbstractProduct {
  9. public:
  10.     ConcreteProductA_1() {
  11.         printf("ConcreteProductA_1 created!\n");
  12.     }
  13.     void do_something() {
  14.         printf("ConcreteProductA_1 do something.\n");
  15.     }
  16. };
  17. class ConcreteProductA_2 : public AbstractProduct {
  18. public:
  19.     ConcreteProductA_2() {
  20.         printf("ConcreteProductA_2 created!\n");
  21.     }
  22.     void do_something() {
  23.         printf("ConcreteProductA_2 do something.\n");
  24.     }
  25. };
  26. class ConcreteFactory {
  27. public:
  28.     AbstractProduct* createProduct(int type){
  29.         AbstractProduct* mProduct = nullptr;
  30.         switch (type) {
  31.         case 1:
  32.             mProduct = dynamic_cast<AbstractProduct*>(new ConcreteProductA_1);
  33.             break;
  34.         case 2:
  35.             mProduct = dynamic_cast<AbstractProduct*>(new ConcreteProductA_2);
  36.             break;
  37.         default:
  38.             printf("unkown product type");
  39.         }
  40.         return mProduct;
  41.     }
  42. };
  43. int main() {
  44.     ConcreteFactory* mFactory = new ConcreteFactory();
  45.     AbstractProduct* mProduct = mFactory->createProduct(1);
  46.     mProduct->do_something();
  47.     return 0;
  48. }
复制代码
抽象工厂

  1. #include <cstdio>
  2. class AbstractProduct {
  3. public:
  4.     virtual void do_something() = 0;
  5.     virtual ~AbstractProduct() {
  6.         printf("AbstractProduct 虚析构\n");
  7.     }
  8. };
  9. class AbstractProductA : public AbstractProduct {
  10. public:
  11.     // virtual void do_something() = 0;
  12.     virtual void do_something_special_A() = 0;
  13.     virtual ~AbstractProductA() {
  14.         printf("AbstractProductA 虚析构\n");
  15.     }
  16. };
  17. class AbstractProductB : public AbstractProduct {
  18. public:
  19.     virtual void do_something_special_B() = 0;
  20.     virtual ~AbstractProductB() {
  21.         printf("AbstractProductB 虚析构\n");
  22.     }
  23. };
  24. class ConcreteProductA : public AbstractProductA {
  25. public:
  26.     void do_something() {
  27.         printf("ConcreteProductA  do_something\n");
  28.     }
  29.     void do_something_special_A() {
  30.         printf("ConcreteProductA  do_something_special_A\n");
  31.     }
  32. };
  33. class ConcreteProductB : public AbstractProductB {
  34. public:
  35.     void do_something() {
  36.         printf("ConcreteProductB  do_something\n");
  37.     }
  38.     void do_something_special_A() {
  39.         printf("ConcreteProductB  do_something_special_B\n");
  40.     }
  41. };
  42. class AbstractFactory {
  43. public:
  44.     virtual AbstractProduct* createProduct(int type) = 0;
  45.     virtual ~AbstractFactory() {
  46.         printf("AbstractFactory 虚析构\n");
  47.     }
  48. };
  49. class ConcreteFactoryA : public AbstractFactory {
  50. public:
  51.     AbstractProduct* createProduct(int type) {
  52.         AbstractProduct* mProduct = nullptr;
  53.         mProduct = dynamic_cast<AbstractProduct*>(new ConcreteProductA);
  54.         return mProduct;
  55.     }
  56. };
  57. int main() {
  58.     AbstractFactory* mFactory = nullptr;
  59.     AbstractProduct* mProduct = nullptr;
  60.     mFactory = new ConcreteFactoryA();
  61.     mProduct = mFactory->createProduct(1);
  62.     mProduct->do_something();
  63.     delete mProduct;
  64.     delete mFactory;
  65.     // mFactory = new ConcreteFactoryB();
  66.     return 1;
  67. }
复制代码
建造者模式

概念

当我们要创建的对象很复杂的时候(通常是由很多其他的对象组合而成),我们要要复杂对象的创建过程和这个对象的表示(展示)分离开来,这样做的利益就是通过一步步的进行复杂对象的构建,由于在每一步的构造过程中可以引入参数,使得经过相同的步骤创建末了得到的对象的展示不一样。


  • Builder 模式的关键是此中的 Director对象并不直接返回对象,而是通过一步步(BuildPartA,BuildPartB,BuildPartC)来一步步进行对象的创建。
  • Builder 模式的示例代码中,BuildPart 的参数是通过客户程序员传入的,这里使用“user-defined”代替,实际的可在 Construct 方法中传入这 3 个参数,这样就可以得到不同的眇小差别的复杂对象了。
Builder 模式和 AbstractFactory 模式在功能上很相似,因为都是用来创建大的复杂的对象,它们的区别是Builder 模式夸大的是一步步创建对象,并通过相同的创建过程可以获得不同的结果对象,一般来说 Builder 模式中对象不是直接返回的。而在 AbstractFactory 模式中对象是直接返回的,AbstractFactory 模式夸大的是为创建多个相互依赖的对象提供一个同一的接口。
code

  1. #include <cstdio>
  2. #include <iostream>
  3. class Product {
  4. public:
  5.     std::string name;
  6.     int level;
  7.     void do_print() {
  8.         printf("name = %s, level = %d \n", name.c_str(), level);
  9.     }
  10. };
  11. class Builder {
  12. public:
  13.     Product* mProduct = nullptr;
  14.     void set_product(Product* product) {
  15.         this->mProduct = product;
  16.     }
  17.     Product* get_product() {
  18.         return this->mProduct;
  19.     }
  20.     void build_name(std::string name) {
  21.         if (this->mProduct)
  22.             this->mProduct->name = name;
  23.     }
  24.     void build_level(int level) {
  25.         if (this->mProduct)
  26.             this->mProduct->level = level;
  27.     }
  28. };
  29. class Director {
  30. public:
  31.     Builder* mBuilder = nullptr;
  32.     void set_builder(Builder* builder) {
  33.         this->mBuilder = builder;
  34.     }
  35.     void do_build(std::string name, int level) {
  36.         Product* product = this->mBuilder->get_product();
  37.         this->mBuilder->build_name(name);
  38.         this->mBuilder->build_level(level);
  39.     }
  40. };
  41. int main() {
  42.     Product* mProduct = new Product;
  43.     Builder* mBuilder = new Builder;
  44.     Director* mDirector = new Director;
  45.     mBuilder->set_product(mProduct);
  46.     mDirector->set_builder(mBuilder);
  47.     mDirector->do_build("张三", 100);
  48.     mProduct->do_print();
  49.     return 0;
  50. }
复制代码
原型模式

Prototype 模式(原型模式)
界说:Prototype 模式也正是提供了自我复制的功能,就是说新对象的创建可以通过已有对象进行创建。在 C++中拷贝构造函数(Copy Constructor)曾经是很对程序员的噩梦,拷贝又分为浅拷贝和深拷贝


  • 浅拷贝:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。
  • 深拷贝:将一个对象复制后,岂论是基本数据类型另有引用类型,都是重新创建的。简朴来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。clone显着是深复制,clone出来的对象是是不能去影响原型对象的
Prototype 模式提供了一个通过已存在对象进行新对象创建的接口(Clone),Clone接口在 C++中我们将通过拷贝构造函数实现。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告
回复

使用道具 举报

© 2001-2025 Discuz! Team. Powered by Discuz! X3.5

GMT+8, 2025-7-10 01:34 , Processed in 0.076178 second(s), 29 queries 手机版|qidao123.com技术社区-IT企服评测▪应用市场 ( 浙ICP备20004199 )|网站地图

快速回复 返回顶部 返回列表