类的设计模式——单例、工厂以及建造者模式

1.单例模式

1.1 饿汉模式

单例模式:一个类只能创建一个对象,这个设计模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。

饿汉模式指在程序初始化时就创建一个唯一的实例对象。适用于多线程环境。他的初始化发生在Singleton Singleton::sig这里。

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

class Singleton{
    static Singleton sig;
private:
    Singleton():_data(100){std::cout<<"我被初始化了"<<std::endl;}
    ~Singleton(){}
public:
    Singleton(const Singleton& sig) = delete;
    Singleton operator=(const Singleton& sig) = delete;
    Singleton& getSig()
    {
        return sig;
    }
private:
    int _data;
};

Singleton Singleton::sig;


int main()
{
    return 0;
}

1.2 懒汉模式

懒汉模式第一次使用单例对象的时候创建实例对象。

这里右两份代码,一份是通过锁来完成一份是通过C++11的static特性完成

cpp 复制代码
class Singleton2
{
    static Singleton2 *sig2;
    static pthread_mutex_t mutex;

private:
    Singleton2() : _data(100)
    {
        std::cout << "我被初始化了 2" << std::endl;
        pthread_mutex_init(&mutex, nullptr);
    }
    ~Singleton2() { pthread_mutex_destroy(&mutex); }

public:
    Singleton2(const Singleton2 &sig) = delete;
    Singleton2 operator=(const Singleton2 &sig) = delete;
    static Singleton2* getSig()
    {
        if (sig2 == nullptr)
        {
            pthread_mutex_lock(&mutex);
            if (sig2 == nullptr)
                sig2 = new Singleton2;
            pthread_mutex_unlock(&mutex);
        }
        return sig2;
    }

private:
    int _data;
};

Singleton2 *Singleton2::sig2 = nullptr;
pthread_mutex_t Singleton2::mutex;
cpp 复制代码
template <typename T>
class Singleton
{
private:
    Singleton() {}
    ~Singleton() {}

public:
    Singleton(const Singleton &) = delete;
    Singleton &operator=(const Singleton &) = delete;
    static T &getInstance()
    {
        static Singleton _eton;
        return _eton;
    }
};

2.工厂模式

工厂模式是一种创建型设计模式,他提供一种创建对象的最佳方式。在工厂模式中,我们创建对象时不会对上层暴露创建逻辑(方便用户操作),而是通过使用一个共同结构来指向新创建的对象,以此实现创建 使用的分离

2.1 简单工厂模式

简单工厂实现由一个工厂对象通过类型决定创建出来指定产品类的实例。

cpp 复制代码
class product_abstract_class{
public:
    product_abstract_class(){}
    virtual void show() = 0;
};

class product1_class : public product_abstract_class
{
public:
    product1_class(){}
    void show() override
    {std::cout<<"this is product 1"<<std::endl;}
};

class product2_class : public product_abstract_class
{
public:
    product2_class(){}
    void show() override
    {std::cout<<"this is product 2"<<std::endl;}
};

class factory{
public:
    static std::shared_ptr<product_abstract_class> generate_instances(const std::string &name)
    {
        if(name == "product 1") return std::make_shared<product1_class>();
        else return std::make_shared<product2_class>();
    }
};

2.2 工厂方法模式

工厂方法模式:在简单工厂模式下新增多个工厂,每个产品对应一个工厂。

cpp 复制代码
class product_abstract_class{
public:
    product_abstract_class(){}
    virtual void show() = 0;
};

class product1_class : public product_abstract_class
{
public:
    product1_class(){}
    void show() override
    {std::cout<<"this is product 1"<<std::endl;}
};

class product2_class : public product_abstract_class
{
public:
    product2_class(){}
    void show() override
    {std::cout<<"this is product 2"<<std::endl;}
};

// class factory{
// public:
//     static std::shared_ptr<product_abstract_class> generate_instances(const std::string &name)
//     {
//         if(name == "product 1") return std::make_shared<product1_class>();
//         else return std::make_shared<product2_class>();
//     }
// };

class factory_abstract_class{
public:
    virtual std::shared_ptr<product_abstract_class> create() = 0;    
};

class product1_factory : public factory_abstract_class
{
public:
    std::shared_ptr<product_abstract_class> create() override
    {
        return std::make_shared<product1_class>();
    }
};

class product2_factory : public factory_abstract_class
{
public:
    std::shared_ptr<product_abstract_class> create() override
    {
        return std::make_shared<product2_class>();
    }
};

工厂方法模式每次增加一个产品时,都需要增加一个具体的产品类和工厂类,这会让系统中类的个数成倍增加,在一定程度上增加了系统的耦合度。

而且工厂方法模式会让代码感觉很冗余,但是又必不可少,无法优化

2.3 抽象工厂模式

抽象工厂模式在工厂方法模式中引入了工厂等级结构。

我感觉就是工厂分类,比如香蕉苹果属于水果那么就通过水果工厂生产,狗和猫属于动物就通过动物工厂来生产

cpp 复制代码
class abs_fruit
{
public:
    abs_fruit(){}
    virtual void show() = 0;
};

class apple_fruit : public abs_fruit
{
public:
    void show() override
    {std::cout<<"this is apple"<<std::endl;}
};

class banana_fruit : public abs_fruit
{
public:
    void show() override
    {std::cout<<"this is banana"<<std::endl;}
};


class abs_animal
{
public:
    abs_animal(){}
    virtual void show() = 0;
};

class cat : public abs_animal
{
public:
    void show() override
    {std::cout<<"this is cat"<<std::endl;}
};

class dog : public abs_animal
{
public:
    void show() override
    {std::cout<<"this is dog"<<std::endl;}
};

class abs_factory
{
public:
    virtual std::shared_ptr<abs_fruit> create_fruit(const std::string &name) = 0;
    virtual std::shared_ptr<abs_animal> create_animal(const std::string &name) = 0;
};

class fruit_factory : public abs_factory
{
public:
    std::shared_ptr<abs_fruit> create_fruit(const std::string &name) override
    {
        if(name == "apple") return std::make_shared<apple_fruit>();
        else if(name == "banana") return std::make_shared<banana_fruit>();
        else return std::shared_ptr<abs_fruit>();
    }

    virtual std::shared_ptr<abs_animal> create_animal(const std::string &name) override
    {
        return std::shared_ptr<abs_animal>();
    }
};

class animal_factory : public abs_factory
{
public:
    std::shared_ptr<abs_fruit> create_fruit(const std::string &name) override
    {
        return std::shared_ptr<abs_fruit>();
    }

    virtual std::shared_ptr<abs_animal> create_animal(const std::string &name) override
    {
        if(name == "cat") return std::make_shared<cat>();
        else if(name == "dog") return std::make_shared<dog>();
        else return std::shared_ptr<abs_animal>();
    }
};

class produce_factory
{
public:
    static std::shared_ptr<abs_factory> create_factory(const std::string& name)
    {
        if(name == "fruit") return std::make_shared<fruit_factory>();
        else if(name == "animal") return std::make_shared<animal_factory>();
        else return std::shared_ptr<abs_factory>();
    }
};

3.建造者模式

建造者模式是一种创建型设计模式,使用多个简单的对象一步一步构建一个复杂对象,能够将一个复杂对象的构建与它的表示分离,提供一种创建对象的最佳方式。

主要用于解决对象的构建过于复杂的问题

建造者模式的五个核心类

抽象产品类:用于给具体的产品类继承

具体的产品类:具体的产品对象类

抽象Builder(建造)类:创建一个产品对象所需的各个部件的抽象接口

具体产品的Builder类:实现抽象接口,构建各个部件

指挥者Director类:统一组建过程,提供给调用者使用,通过指挥者来构造产品

cpp 复制代码
//---------------------------------------建造者模式-----------------------------------------------

//抽象产品类
class Computer
{
public:
    using ptr = std::shared_ptr<Computer>; //为std::shared_ptr<Computer>创建类型别名ptr    using等价于typedef
    Computer(){}
    void setboard(const std::string &board){_board = board;}
    void setdisplay(const std::string &display){_display = display;}
    virtual void setos() = 0;
    virtual ~Computer(){};
public:
    std::string to_string()
    {
        std::string retstr = "os : "+_os+" "+"board : "+_board+" "+"display : "+_display;
        return retstr;
    }
protected:
    std::string _board;
    std::string _display;
    std::string _os;
};

//具体产品类
class MacBook : public Computer
{
public:
    using ptr = std::shared_ptr<MacBook>; 
    void setos() override
    { _os = "Max Os X12";}
};

//抽象建造者类
class Builder
{
public:
    using ptr = std::shared_ptr<Builder>;
    virtual void builder_board(const std::string &board) = 0;
    virtual void builder_display(const std::string &display) = 0;
    virtual void builder_os() = 0;
public:
    virtual Computer::ptr builder() = 0; // 用于建造对象
};

//具体产品建造者类
class MacBook_Builder : public Builder
{
public:
    MacBook_Builder() :_computer(new MacBook()){}
public:
    void builder_board(const std::string &board)
    {
        _computer->setboard(board);
    }
    void builder_display(const std::string &display)
    {
        _computer->setdisplay(display);
    }
    void builder_os()
    {
        _computer->setos();
    }
    Computer::ptr builder()
    {
        return _computer;
    }
private:
    Computer::ptr _computer;
};

//指挥者类
class Director
{
public:
    Director(Builder* builder) :_builder(builder){}
    void construct(const std::string &board,const std::string &display)
    {
        _builder->builder_board(board);
        _builder->builder_display(display);
        _builder->builder_os();
    }
private:
    Builder::ptr _builder;
};


int main()
{
    Builder* dp = new MacBook_Builder;
    std::shared_ptr<Director> dir(new Director(dp)); 
    dir->construct("英特尔主板","VOC显示器");
    Computer::ptr tmp = dp->builder();    //这才是我们的目标对象(想要创建的对象)
    std::cout<<tmp->to_string()<<std::endl;

    return 0;
}
相关推荐
on the way 1236 小时前
创建型设计模式之Prototype(原型)
设计模式·原型模式
琢磨先生David14 小时前
Java 可扩展状态系统设计:备忘录模式的工程化实践与架构演进
java·设计模式·架构
琢磨先生David17 小时前
Java 迭代器模式:遍历数据集合的优雅之道
java·设计模式·迭代器模式
秋田君20 小时前
深入理解JavaScript设计模式之call,apply,this
javascript·设计模式
master-dragon21 小时前
设计模式-单例模式
java·单例模式·设计模式
hstar95271 天前
三十一、面向对象底层逻辑-SpringMVC九大组件之RequestToViewNameTranslator接口设计哲学
java·spring·设计模式·架构
张萌杰1 天前
设计模式26——解释器模式
设计模式·解释器模式
蔡蓝1 天前
设计模式-依赖倒转原则
设计模式
{⌐■_■}1 天前
【设计模式】简单工厂模式,工厂模式,抽象工厂模式,单例,代理,go案例区分总结
开发语言·redis·后端·设计模式·golang·简单工厂模式·抽象工厂模式
暴躁哥1 天前
深入理解设计模式之状态模式
设计模式·状态模式