NOTES / COMPUTER

创建型设计模式

对象创建相关的模式与实现笔记。

单例模式

全局只存在一个实例对象,一般用于日志类。全局共享一个实例的方法和数据,可以节约内存简便一些操作。 1、懒汉模式:在类加载时持全局实例对象,线程安全但是无论是否使用都会存在该实例。 2、饿汉模式:在首次使用时创建实例对象,延迟加载但线程不安全,需要双重检查锁定

class Singleton {
public:
    // 懒汉模式
    static Singleton& getInstanceBeforeUse() {
        // 局部静态c++11特性
        static Singleton instance;
        return instance;
    }
    // 饿汉模式
    static Singleton& getInstanceAfterUse() {
        // 未进入临界区
        if (instance == nullptr) {
            // 双重检查锁定
            // 进入临界区
            std::lock_guard<std::mutex> lock(mutex);
            if(instance == nullptr){
                instance = new Singleton();
            }
        }
        return *instance;
    }
private:
    Singleton() {}  // 私有构造函数
    ~Singleton() {} // 私有析构函数
    Singleton(const Singleton&) = delete;            // 禁用拷贝构造函数
    Singleton& operator=(const Singleton&) = delete; // 禁用赋值操作
    static Singleton instance;                       // 单例实例
};

// Singleton* Singleton::instance = nullptr;

工厂模式

简单工厂

简单工厂模式:通过工厂类来创建对象,工厂类只负责创建对象,而不关心创建过程。仅建需要创建的对象进行抽象。

enum class WorkerType {
    UI,
    IT
};
struct Worker{};
struct UI: Worker{};
struct IT: Worker{};

struct Department{
    Worker* CreatWorker(WorkerType Type){
        switch (Type) {
            case WorkerType::UI:{
                return new UI();
            }
            case WorkerType::IT:{
                return new IT();
            }
            default: std::cout << "Not have Type" << std::endl;
        }
    }
};

// 通过实例对象工厂进行创建
Department department{};
department.CreatWorker(WorkerType::UI);

工厂方法

工厂方法设计模式是允许定义一个接口,用于创建相关或依赖对象的家族,而不需要指定具体的类。在简单工厂的基础上,抽象了工厂的创建方法。

struct Worker{
    virtual int getUID() =0;
};
struct UI: Worker{
    UI(){std::cout << "Create UI" << std::endl;}
    int getUID(){
        const auto id = rand();
        std::cout << "UI UID: " << id << std::endl;
        return id;
    }
};
struct IT: Worker{
    IT(){std::cout << "Create IT" << std::endl;}
    int getUID(){
        const auto id = rand();
        std::cout << "IT UID: " << id << std::endl;
        return id;
    }
};
// 工厂基类
struct Department{
    virtual Worker* CreatWorker() =0;
    // 不同对象在创建后有着相对统一的行为。
    void punchCad(){
        Worker* worker = this->CreatWorker();
        worker->getUID();
        delete worker;
    }
};
// 不同类型的工厂
struct UIFactory: Department{
    UI* CreatWorker(){ return  new UI();}
};
struct ITFactory: Department{
    IT* CreatWorker(){ return new IT();}
};

// 使用对应的工厂进行创建,可以动态的调用 punchCad
ITFactory factory{};
factory.punchCad();

抽象工厂

进一步进行抽象,将工厂和创建对象分开,可以创建多个产品。 抽象工厂模式是工厂方法模式的升级版,它扩展了工厂方法模式, 为创建一组相关或相互依赖的对象提供一个接口。 抽象工厂模式还解决了工厂方法模式中,产品等级结构中产品之间的耦合问题。

// 项目
struct Project{
    virtual void assignTo(int id) =0;
};
// 项目的不同类似
struct Code: Project{
    void assignTo(int id){
        std::cout << "ID: "  << id << "to code." << std::endl;
    }
};
struct Draw: Project{
    void assignTo(int id){
        std::cout << "ID: "  << id << "to draw." << std::endl;
    }
};

// 员工
struct Worker{
    virtual int getUID() =0;
};
// 员工的不同类型
struct UI: Worker{
    UI(){std::cout << "Create UI" << std::endl;}
    int getUID(){
        const auto id = rand();
        std::cout << "UI UID: " << id << std::endl;
        return id;
    }
};
struct IT: Worker{
    IT(){std::cout << "Create IT" << std::endl;}
    int getUID(){
        const auto id = rand();
        std::cout << "IT UID: " << id << std::endl;
        return id;
    }
};
// 工厂基类
struct Department{
    virtual Worker* CreatWorker() const=0;
    virtual Project* CreatProject() const =0;
};
// 不同类型的工厂
struct UIFactory: Department{
    UI* CreatWorker () const { return  new UI();}
    Draw* CreatProject() const { return new Draw();}

};
struct ITFactory: Department{
    IT* CreatWorker() const { return new IT();}
    Code* CreatProject() const { return new Code();}
};

struct DepartmentManager{
    const Department& department;
    std::vector<Project*> projects;
    std::unordered_map<int, Worker*> works;
    DepartmentManager(const Department& department): department(department){}
    Project* ManagerCreatProject(){
        Project* project = department.CreatProject();
        projects.push_back(project);
        return project;
    }
    int ManagerCreatWorker() {
        Worker* worker = department.CreatWorker();
        int id = worker->getUID();
        works[id] = worker;
        return id;
    }
};

// 使用方式差不多,但是做了一个更统一的管理
ITFactory department;
DepartmentManager Manager(department);
Project* project = Manager.ManagerCreatProject();
int id = Manager.ManagerCreatWorker();
project->assignTo(id);
ZYK · 笔记与实践返回首页