设计模式之单例模式&工厂模式

121 阅读1分钟

前言

《⼤话设计模式》⼀书中提到 24 种设计模式,但是目前阶段经常用到的就是单例模式和工厂模式,在此记录一下单例模式和工厂模式的特点,并附上C++代码实现。

设计模式还有6大原则,在这里就不赘述了,感觉太过于教条主义了,也记不住。

一、单例模式

特点: 保证一个类仅有一个实例,并提供一个访问它的全局访问点。

在开发过程中,很多时候一个类我们希望它只创建一个对象,这个时候就需要用到单例模式了。

1.1 饿汉模式

饿汉模式就是在又一开始的时候类的对象就已经创建完成,方法是类里面包含一个静态方法。

该方法返回一个指向该类对象的指针,该方法是static公有的。

#include <mutex>
#include <iostream>
using namespace std;

/*
//饿汉模式
class SingleInstace{
public:
    static SingleInstace* getInstance()
    {
        static SingleInstace instance;//注意是static的
        return &instance;
    }
//涉及到对象创建的函数都设为private的
private:
    SingleInstace(){cout<<"这里是饿汉模式的构造函数"<<endl;}
    SingleInstace(const SingleInstace& other){}
    SingleInstace& operator=(const SingleInstace& other){return *this;}
};

int main()
{
    //因为不能创建对象所以通过静态成员函数的⽅法返回静态成员变
    SingleInstace* instance = SingleInstace::getInstance();
    return 0;
}

1.2 懒汉模式

尽可能的晚的创建这个对象的实例,即在单例类第⼀次被引⽤的时候就将⾃⼰初始化。

代码如下:


#include <mutex>
#include <iostream>
using namespace std;


class SingleInstace{
public:
    static SingleInstace* getInstance()
    {
        if(instance == nullptr)
        {
            m.lock();
            instance = new SingleInstace();
            m.unlock();
        }
        return instance;
    }
//涉及到对象创建的函数都设为private的
private:
    SingleInstace(){cout<<"这里是懒汉模式的构造函数"<<endl;}
    SingleInstace(const SingleInstace& other){}
    SingleInstace& operator=(const SingleInstace& other){return *this;}
    static SingleInstace* instance;
    static mutex m;
};

SingleInstace* SingleInstace::instance = nullptr;
mutex SingleInstace::m;//类中的static变量需要在外部定义初始化

int main()
{
    //因为不能创建对象所以通过静态成员函数的⽅法返回静态成员变
    SingleInstace* instance = SingleInstace::getInstance();
    return 0;
}

单例模式的适⽤场景

  • 系统只需要⼀个实例对象,或者考虑到资源消耗的太⼤⽽只允许创建⼀个对象。

  • 客户调⽤类的单个实例只允许使用⼀个公共访问点,除了该访问点之外不允许通过其它

⽅式访问该实例(就是共有的静态⽅法)。

二、工厂模式

就是建⽴⼀个⼯⼚类,对实现了同⼀接⼝的⼀些类进⾏实例的创建。简单⼯⼚模式的实质是由⼀个⼯⼚类根据传⼊的参数,动态决定应该创建哪⼀个产品类(这些产品类继承⾃⼀个⽗类)的实例。

简单来说就是:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

下面是一个cpp代码示例:

#include <mutex>
#include <iostream>
using namespace std;

class Product{
public:
    virtual void show() = 0;//纯虚函数
};

class ProductA : public Product{
public:
    ProductA(){};
    void show()
    {
        cout<<"这里是A"<<endl;
    }
};

class ProductB : public Product{
public:
    ProductB(){};
    void show()
    {
        cout<<"这里是B"<<endl;
    };
};

class Factory{
public:
    Factory(){}
    Product* product(string s)
    {
        if(s == "A")
            return new ProductA();//如果之前的继承不写明是public的,这里就会报错
        else if(s == "B")
            return new ProductB();
        return nullptr;
    }
};

int main()
{
    Factory factory;
    Product* prod;

    prod = factory.product("B");
    prod->show();

    prod = factory.product("A");
    prod->show();
    return 0;
}

⼯⼚模式⽬的就是代码解耦,如果我们不采⽤⼯⼚模式,如果要创建产品 A、B,通常做法采⽤ switch...case语句,那么想⼀想后期添加更多的产品进来,我们要添加更多的switch...case ,这样就很麻烦,⽽且也不符合设计模式中的开放封闭原则。