设计模式 - 创建型

创建型

分类原因

创建型设计模式抽象了实例化过程。

  • 它们帮助一个系统独立于 一些对象

    • 创建它的对象

    • 组合它的对象

    • 表示它的对象

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

    • 使用哪些具体的类
    • 这些类的实例是如何被创建和被放在一起的。
  • 创建型模式,给予了灵活性

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

单例模式,工厂方法模式,抽象工厂模式,建造者模式,原型模式

对象创建
Factory 模式 被实例化的子类
AbstactFactory 模式 产品对象家族
Prototype 模式 针对被实例化的类
Builder 模式 如何创建一个组合对象
对象创建&对象性能
Singleton 模式 针对一个类的唯一实例

单例模式

用途

实现单例模式的步骤:

1、构造函数私有化

2、增加静态私有的当前类的指针变量

3、提供静态对外接口,可以让用户获得单例对象

饿汉式

饿汉式:

  • 还没有使用该单例对象,该单例对象就已经被加载到内存了
  • 在对象过多时会造成内存浪费

需要在main函数前,为单例对象赋值。

shell 复制代码
instance created hungryly.
process started !
waiting done.
got instance
m property is  2 
process exit
cpp 复制代码
#include <cstdio>
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;

class Singleton_hungry{
private:
    int mProp = 0;
    Singleton_hungry(int intParam = 1):mProp(intParam) {
        printf("instance created hungryly.\n");
    };
    ~Singleton_hungry() {
        if (mInstance) {
            delete mInstance;
        }
        printf("instance deleted.\n");
    }

public:
    static Singleton_hungry* mInstance;
    static Singleton_hungry* getInstance() {
        printf("got instance\n");
        if (mInstance) {
            return mInstance;
        }
        mInstance = new Singleton_hungry;
        return mInstance;
    }
    void do_print() {
        printf("m property is  %d \n", mProp);
    }
};

//以下语句需要在main函数运行前执行
Singleton_hungry* Singleton_hungry::mInstance = new Singleton_hungry(2);


int main() {
    Singleton_hungry* mHungryPtr;
    printf("process started !\n");
    std::this_thread::sleep_for(std::chrono::milliseconds(400));
    printf("waiting done.\n");
    mHungryPtr = Singleton_hungry::getInstance();
    mHungryPtr->do_print();
    std::this_thread::sleep_for(std::chrono::milliseconds(400));
    printf("process exit\n");
    return 1;
}
懒汉式

懒汉式:

  • 避免了内存浪费
  • 引入新问题:线程不安全------可以通过互斥量来解决。线程不安全的问题。
cpp 复制代码
#include <cstdio>
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;

class Singleton_hungry{
private:
    int mProp = 0;
    Singleton_hungry(int intParam = 1):mProp(intParam) {
        printf("instance created hungryly.\n");
    };
    ~Singleton_hungry() {
        if (mInstance) {
            delete mInstance;
        }
        printf("instance deleted.\n");
    }

public:
    static Singleton_hungry* mInstance;
    static Singleton_hungry* getInstance() {
        printf("got instance\n");
        if (mInstance) {
            return mInstance;
        }
        mInstance = new Singleton_hungry;
        return mInstance;
    }
    void do_print() {
        printf("m property is  %d \n", mProp);
    }
};

//以下语句需要在main函数运行前执行
Singleton_hungry* Singleton_hungry::mInstance = new Singleton_hungry(2);


int main() {
    Singleton_hungry* mHungryPtr;
    Singleton_hungry* mHungryPtr2;
    printf("process started !\n");

    std::this_thread::sleep_for(std::chrono::milliseconds(400));
    printf("waiting done.\n");
    mHungryPtr = Singleton_hungry::getInstance();
    mHungryPtr2 = Singleton_hungry::getInstance();
    if (mHungryPtr != mHungryPtr2) {
        printf("fail to get instance \n");
    } else {
        printf("get same instance\n");
    }

    std::this_thread::sleep_for(std::chrono::milliseconds(400));
    printf("process exit\n");
    return 1;
}

工厂模式

cpp 复制代码
#include <cstdio>
#include <iostream>

using namespace std;

class AbstractProduct {
public:
virtual void do_something() = 0;
};

class ConcreteProductA_1 : public AbstractProduct {
public:
    ConcreteProductA_1() {
        printf("ConcreteProductA_1 created!\n");
    }
    void do_something() {
        printf("ConcreteProductA_1 do something.\n");
    }
};

class ConcreteProductA_2 : public AbstractProduct {
public:
    ConcreteProductA_2() {
        printf("ConcreteProductA_2 created!\n");
    }
    void do_something() {
        printf("ConcreteProductA_2 do something.\n");
    }
};

class ConcreteFactory {
public:
    AbstractProduct* createProduct(int type){
        AbstractProduct* mProduct = nullptr;
        switch (type) {
        case 1:
            mProduct = dynamic_cast<AbstractProduct*>(new ConcreteProductA_1);
            break;
        case 2:
            mProduct = dynamic_cast<AbstractProduct*>(new ConcreteProductA_2);
            break;
        default:
            printf("unkown product type");
        }
        return mProduct;
    }
};

int main() {
    ConcreteFactory* mFactory = new ConcreteFactory();
    AbstractProduct* mProduct = mFactory->createProduct(1);
    mProduct->do_something();
    return 0;
}

抽象工厂

cpp 复制代码
#include <cstdio>
class AbstractProduct {
public:
    virtual void do_something() = 0;
    virtual ~AbstractProduct() {
        printf("AbstractProduct 虚析构\n");
    }
};

class AbstractProductA : public AbstractProduct {
public:
    // virtual void do_something() = 0;
    virtual void do_something_special_A() = 0;
    virtual ~AbstractProductA() {
        printf("AbstractProductA 虚析构\n");
    }
};

class AbstractProductB : public AbstractProduct {
public:
    virtual void do_something_special_B() = 0;
    virtual ~AbstractProductB() {
        printf("AbstractProductB 虚析构\n");
    }
};

class ConcreteProductA : public AbstractProductA {
public:
    void do_something() {
        printf("ConcreteProductA  do_something\n");
    }
    void do_something_special_A() {
        printf("ConcreteProductA  do_something_special_A\n");
    } 
};

class ConcreteProductB : public AbstractProductB {
public:
    void do_something() {
        printf("ConcreteProductB  do_something\n");
    }
    void do_something_special_A() {
        printf("ConcreteProductB  do_something_special_B\n");
    } 
};

class AbstractFactory {
public:
    virtual AbstractProduct* createProduct(int type) = 0;
    virtual ~AbstractFactory() {
        printf("AbstractFactory 虚析构\n");
    }
};

class ConcreteFactoryA : public AbstractFactory {
public:
    AbstractProduct* createProduct(int type) {
        AbstractProduct* mProduct = nullptr;
        mProduct = dynamic_cast<AbstractProduct*>(new ConcreteProductA);
        return mProduct;
    }
};

int main() {
    AbstractFactory* mFactory = nullptr;
    AbstractProduct* mProduct = nullptr;
    mFactory = new ConcreteFactoryA();
    mProduct = mFactory->createProduct(1);
    mProduct->do_something();
    delete mProduct;
    delete mFactory;

    // mFactory = new ConcreteFactoryB();

    return 1;
}

建造者模式

概念

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

  • Builder 模式的关键是其中的 Director对象并不直接返回对象,而是通过一步步(BuildPartA,BuildPartB,BuildPartC)来一步步进行对象的创建。
  • Builder 模式的示例代码中,BuildPart 的参数是通过客户程序员传入的,这里使用"user-defined"代替,实际的可在 Construct 方法中传入这 3 个参数,这样就可以得到不同的细微差别的复杂对象了。

Builder 模式和 AbstractFactory 模式在功能上很相似,因为都是用来创建大的复杂的对象,它们的区别是Builder 模式强调的是一步步创建对象,并通过相同的创建过程可以获得不同的结果对象,一般来说 Builder 模式中对象不是直接返回的。而在 AbstractFactory 模式中对象是直接返回的,AbstractFactory 模式强调的是为创建多个相互依赖的对象提供一个同一的接口。

code
cpp 复制代码
#include <cstdio>
#include <iostream>

class Product {
public:
    std::string name;
    int level;
    void do_print() {
        printf("name = %s, level = %d \n", name.c_str(), level);
    }
};

class Builder {
public:
    Product* mProduct = nullptr;
    void set_product(Product* product) {
        this->mProduct = product;
    }
    Product* get_product() {
        return this->mProduct;
    }
    void build_name(std::string name) {
        if (this->mProduct)
            this->mProduct->name = name;
    }
    void build_level(int level) {
        if (this->mProduct)
            this->mProduct->level = level;
    }

};

class Director {
public:
    Builder* mBuilder = nullptr;
    void set_builder(Builder* builder) {
        this->mBuilder = builder;
    }
    void do_build(std::string name, int level) {
        Product* product = this->mBuilder->get_product();

        this->mBuilder->build_name(name);
        this->mBuilder->build_level(level);
    }
};


int main() {
    Product* mProduct = new Product;
    Builder* mBuilder = new Builder;
    Director* mDirector = new Director;
    mBuilder->set_product(mProduct);
    mDirector->set_builder(mBuilder);
    mDirector->do_build("张三", 100);
    mProduct->do_print();


    return 0;
}

原型模式

Prototype 模式(原型模式)

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

  • 浅拷贝:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。

  • 深拷贝:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。clone明显是深复制,clone出来的对象是是不能去影响原型对象的

Prototype 模式提供了一个通过已存在对象进行新对象创建的接口(Clone),Clone接口在 C++中我们将通过拷贝构造函数实现。

相关推荐
Death20032 分钟前
PCL库中的算法封装详解
c++·qt·算法·3d
勇敢滴勇33 分钟前
【C++】继承和多态常见的面试问题
java·c++·面试
Qhumaing41 分钟前
小白C/C++语言常见问题(持续更新)
c语言·c++·算法
小柯J桑_1 小时前
C++:二叉搜索树(迭代)
c++·二叉搜索树
铭正1 小时前
c++时间形式转换
c++·时间格式转换
flying robot1 小时前
编程语言的设计模式
设计模式
啦啦啦!1 小时前
2024年10月30日(双指针算法)
c++·算法·leetcode
山川尔尔_2 小时前
2025前端面试-浏览器的事件循环和浏览器的事件循环的区别是什么---002
前端·javascript·面试
△曉風殘月〆2 小时前
C#与C++结构体的交互
c++·c#·p/invoke
hugerat2 小时前
嵌入式linux跨平台基于mongoose的TCP C++类的源码
linux·c++·tcp/ip