设计模式 - 创建型

创建型

分类原因

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

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

    • 创建它的对象

    • 组合它的对象

    • 表示它的对象

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

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

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

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

对象创建
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++中我们将通过拷贝构造函数实现。

相关推荐
吃个早饭1 小时前
2025年第十六届蓝桥杯大赛软件赛C/C++大学B组题解
c语言·c++·蓝桥杯
阿沁QWQ2 小时前
单例模式的两种设计
开发语言·c++·单例模式
六bring个六2 小时前
qtcreater配置opencv
c++·qt·opencv·计算机视觉·图形渲染·opengl
qwertyuiop_i2 小时前
pe文件二进制解析(用c/c++解析一个二进制pe文件)
c语言·c++·pe文件
yxc_inspire3 小时前
基于Qt的app开发第八天
开发语言·c++·qt
June`4 小时前
专题三:穷举vs暴搜vs深搜vs回溯vs剪枝(全排列)决策树与递归实现详解
c++·算法·深度优先·剪枝
我叫珂蛋儿吖4 小时前
[redis进阶六]详解redis作为缓存&&分布式锁
运维·c语言·数据库·c++·redis·分布式·缓存
yxc_inspire5 小时前
基于Qt的app开发第七天
开发语言·c++·qt·app
周Echo周5 小时前
20、map和set、unordered_map、un_ordered_set的复现
c语言·开发语言·数据结构·c++·算法·leetcode·list
workflower5 小时前
使用谱聚类将相似度矩阵分为2类
人工智能·深度学习·算法·机器学习·设计模式·软件工程·软件需求