【C++设计模式】创建型模式(工厂、单例)

设计模式总共有23种,可分为3大类:创建型模式(Creational Patterns)、结构型模式(Structural Patterns)、行为型模式(Behavioral Patterns)。

1. 工厂模式

工厂模式属于创建者模式,提供了一种创建对象的最佳方式。

工厂模式的实现方式有简单工厂模式、工厂方法模式、抽象工厂模式,每个实现方式都存在优和劣。

简单工厂模式与工厂模式的结构组成是:

1. 工厂类:工厂模式的核心类,会定义一个用于创建指定的具体实例对象的接口。(可分为抽象工厂和具体工厂)
2. 抽象产品类:是具体产品类的继承的父类或实现的接口。
3. 具体产品类:工厂类所创建的对象就是此具体产品实例。

以汽车厂为例:

Cars为汽车的抽象类(基类),接口函数为Show(),用于显示文本。

Benzi、Audi、Bmw为具体汽车品牌的类,它们都继承于Cars抽象类。

// 汽车抽象类
class Cars
{
    
    
public:
    virtual ~Cars() {
    
    }
    virtual void Show() = 0;
};

// 奔驰
class Benzi: public Cars
{
    
    
public:
    void Show()
    {
    
    
        std::cout << "我是Benzi" << std::endl;
    }
};

// 奥迪
class Audi: public Cars
{
    
    
public:
    void Show()
    {
    
    
        std::cout << "我是Audi" << std::endl;
    }
};

// 宝马
class Bmw: public Cars
{
    
    
public:
    void Show()
    {
    
    
        std::cout << "我是Bmw" << std::endl;
    }
};

CarsFactory为工厂类,类里实现根据汽车类型创建对应产品对象的CreateCars(CARS_TYPE type)函数。

enum CARS_TYPE
{
    
    
    BENZI,
    AUDI,
    BMW
};

// 总车厂
class CarsFactory
{
    
    
public:
    // 根据鞋子类型创建对应的鞋子对象
    Cars *CreateCars(CARS_TYPE type)
    {
    
    
        switch (type)
        {
    
    
        case BENZI:
            return new Benzi();
            break;
        case AUDI:
            return new Audi();
            break;
        case BMW:
            return new Bmw();
            break;
        default:
            return NULL;
            break;
        }
    }
};

main函数,先是构造了工厂对象,然后创建指定类型的具体产品对象,然后输出对应文本。因为采用的是new的方式创建了对象,用完了要通过delete 释放资源资源。

int main()
{
    
    
    // 构造工厂对象
    CarsFactory carsFactory;

    // 从工厂对象创建benzi对象
    Cars *pBenzi = carsFactory.CreateCars(BENZI);
    if (pBenzi != NULL)
    {
    
    
        pBenzi->Show();

        // 释放资源
        delete pBenzi;
        pBenzi = NULL;
    }

    // 从工厂对象创建audi对象
    Cars *pAudi = carsFactory.CreateCars(AUDI);
    if (pAudi != NULL)
    {
    
    
        pAudi ->Show();

        // 释放资源
        delete pAudi ;
        pAudi = NULL;
    }

    // 从工厂对象创建bmw对象
    Cars *pBmw = carsFactory.CreateCars(BMW);
    if (pBmw != NULL)
    {
    
    
        pBmw ->Show();

        // 释放资源
        delete pBmw ;
        pBmw  = NULL;
    }

    return 0;
}

2. 抽象工厂模式

汽车厂为了扩大业务,不只生产汽车了,还生产摩托车。抽象工厂模式可以创建多个工厂和多个产品族。

扫描二维码关注公众号,回复: 14605852 查看本文章

抽象工厂模式的组成:

1. 抽象工厂类:工厂方法模式的核心类,提供创建具体产品的接口,由具体工厂类实现。
2. 具体工厂类:继承于抽象工厂,实现创建对应具体产品对象的方式。
3. 抽象产品类:它是具体产品继承的父类(基类)。
4. 具体产品类:具体工厂所创建的对象,就是此类。

创建基类(抽象产品类):

// 汽车抽象类
class Cars
{
    
    
public:
    virtual ~Cars() {
    
    }
    virtual void Show() = 0;
};

// 奔驰
class BenziCar: public Cars
{
    
    
public:
    void Show()
    {
    
    
        std::cout << "我是Benzi car" << std::endl;
    }
};

// 摩托车抽象类
class Motors
{
    
    
public:
    virtual ~Motors() {
    
    }
    virtual void Show() = 0;
};

// 奔驰
class BenziMotor: public Motors
{
    
    
public:
    void Show()
    {
    
    
        std::cout << "我是Benzi motor" << std::endl;
    }
};

Factory为抽象工厂,提供了创建汽车CreateCars()和摩托车产品CreateMotors()对象的接口。

BenziProducer为具体工厂,实现了创建奔驰汽车和奔驰摩托车的方式。

// 总厂
class Factory
{
    
    
public:
    virtual Cars *CreateCars() = 0;
	virtual Motors *CreateMotors() = 0;
    virtual ~Factory() {
    
    }
};

// benzi生产者/生产链
class BenziProducer : public Factory
{
    
    
public:
    Cars *CreateCars()
    {
    
    
        return new BenziCar();
    }
	
	Motors *CreateMotors()
    {
    
    
        return new BenziMotor();
    }
};

main函数,构造benzi工厂对象,然后创建benzi产品族的汽车和摩托车对象。同样,对象不再使用时,需要手动释放资源。

int main()
{
    
    
    // ================ 生产Benzi流程 ==================== //
    // 生产线
    Factory *benziProducer = new BenziProducer();
    
	// 生产汽车
    Cars *benziCar = benziProducer ->CreateCars();
	// 生产摩托车
    Motors *benziMotor = benziProducer ->CreateMotors();
    
    benziCar->Show();
    benziMotor->Show();
	
    // 释放资源
    delete benziCar;
	delete benziMotor;
    delete benziProducer;

    return 0;
}

3. 单例模式

单例模式是指在整个系统生命周期内,保证一个类只能产生一个实例,确保该类的唯一性。

单例模式可以保证线程安全,即给共享的资源加把锁,保证每个资源变量每时每刻至多被一个线程占用。

单例模式可以分为懒汉式和饿汉式,两者之间的区别在于创建实例的时间不同。懒汉式只有使用时才会创建实例,这种情况要考虑线程安全;饿汉式初始化就会创建实例,需要时直接调用,不用考虑安全问题。

饿汉式实现:

头文件:

// 饿汉实现 /
class Singleton
{
    
    
public:
    // 获取单实例
    static Singleton* GetInstance();

    // 释放单实例,进程退出时调用
    static void deleteInstance();
    
    // 打印实例地址
    void Print();

private:
    // 将其构造和析构成为私有的, 禁止外部构造和析构
    Singleton();
    ~Singleton();

    // 将其拷贝构造和赋值构造成为私有函数, 禁止外部拷贝和赋值
    Singleton(const Singleton &signal);
    const Singleton &operator=(const Singleton &signal);

private:
    // 唯一单实例对象指针
    static Singleton *g_pSingleton;
};

源文件:

// 代码一运行就初始化创建实例 ,本身就线程安全
Singleton* Singleton::g_pSingleton = new (std::nothrow) Singleton();

Singleton* Singleton::GetInstance()
{
    
    
    return g_pSingleton;
}

void Singleton::deleteInstance()
{
    
    
    if (g_pSingleton)
    {
    
    
        delete g_pSingleton;
        g_pSingleton = nullptr;
    }
}

void Singleton::Print()
{
    
    
    std::cout << "我的实例内存地址是:" << this << std::endl;
}

Singleton::Singleton()
{
    
    
    std::cout << "构造函数" << std::endl;
}

Singleton::~Singleton()
{
    
    
    std::cout << "析构函数" << std::endl;
}

main程序:

#include <iostream>
#include <memory>
#include <mutex>

class Singleton {
    
    
public:
    static std::shared_ptr<Singleton> getSingleton();

    void print() {
    
    
        std::cout << "Hello World." << std::endl;
    }

    ~Singleton() {
    
    
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }

private:
    Singleton() {
    
    
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

static std::shared_ptr<Singleton> singleton = nullptr;
static std::once_flag singletonFlag;

std::shared_ptr<Singleton> Singleton::getSingleton() {
    
    
    std::call_once(singletonFlag, [&] {
    
    
        singleton = std::shared_ptr<Singleton>(new Singleton());
    });
    return singleton;
}

4. 建造者模式

建造者模式可以将复杂对象的构建与它的表示分离,使得相同的构建过程可以得到不同的表示。如果说工厂模式和抽象工厂模式更注重产品整体,那建造者模式则更在乎产品的组成和细节。

5. 原型模式

原型模式就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。

以上。

猜你喜欢

转载自blog.csdn.net/qq_40344790/article/details/129658335