C++版设计模式(一):单例模式

设计模式

设计原则:单一职责原则、开放封闭原则、里氏替换原则、最少知识原则、接口隔离原则、依赖倒置原则。

[注]:本系列为个人学习用,主要介绍设计模式相关知识。之后的示意图中借用了菜鸟教程中的结构图,代码为个人原创并且全部可以运行。

一:单例模式

单例模式

c++的单例模式,实际上是一种管理全局变量和静态函数的设计模式。
1. 饿汉式单例
  • 特点

    • 在类加载时就创建实例,线程安全。
    • 类一加载,单例就被实例化,浪费了内存(如果实例始终未被使用)。
  • 实现步骤

    • 将构造函数声明为私有,防止外部创建实例。
    • 创建一个静态实例,并在类加载时初始化。
    • 提供一个静态方法返回实例。
2. 懒汉式单例
  • 特点

    • 在第一次调用获取实例时才创建实例,避免了类加载时立即初始化的问题。
    • 需要注意线程安全问题,如果多个线程同时调用,可能会创建多个实例。
  • 实现步骤

    • 将构造函数声明为私有。
    • 创建一个静态实例变量,但不初始化。
    • 在 getInstance 方法中判断是否已创建实例,如果没有则创建。
3. 双重检查锁
  • 特点

    • 懒汉式基础上增加了线程安全的优化。
    • 通过双重判断和加锁,保证实例只被创建一次,同时减少了锁的性能开销。
  • 实现步骤

    • 外层判断是否为 nullptr,避免进入锁。
    • 内层加锁,并再次判断是否需要初始化。
4. 静态内部类
  • 特点

    • 基于 Java 的类加载机制,利用静态内部类的特点实现延迟加载。
    • 静态内部类在被调用时才会加载,并初始化单例。
  • 实现步骤

    • 外部类构造函数私有。
    • 定义一个静态内部类,内部类中包含单例实例。
    • 提供一个静态方法调用内部类实例。
5. 枚举
  • 特点

    • 最简洁且最安全的实现方式,避免了序列化和反射问题。
    • 通过枚举的唯一性保证单例。
  • 实现步骤

    • 定义一个枚举类型,其中包含单例实例。
    • 提供方法访问该实例。

在这里插入图片描述

简单工厂模式(静态工厂模式)

工厂可以根据参数的不同返回不同的产品
1. 组成
  • Factory(工厂):核心部分,负责实现创建所有产品的内部逻辑,工厂类可以被外界直接调用,创建所需对象
    工厂类是整个模式的关键.包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象.通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了

  • Product(抽象类产品):工厂类所创建的所有对象的父类,封装了产品对象的公共方法,所有的具体产品为其子类对象

  • ProductA、ProductB…(具体产品):简单工厂模式的创建目标,所有被创建的对象都是某个具体类的实例。它要实现抽象产品中声明的抽象方法

#include <bits/stdc++.h>

using namespace std;

// 以披萨为例,创建披萨的工厂类
// 假设有三种披萨,分别为:奶酪披萨、香肠披萨、海鲜披萨
class Pizza
{
public:
    virtual void prepare() = 0;
    virtual void bake() = 0;
    virtual void cut() = 0;
    virtual void box() = 0;
    virtual ~Pizza() {}
};

class CheesePizza : public Pizza
{
public:
    void prepare() override
    {
        cout << "Prepare cheese pizza" << endl;
    }
    void bake() override
    {
        cout << "Bake cheese pizza" << endl;
    }
    void cut() override
    {
        cout << "Cut cheese pizza" << endl;
    }
    void box() override
    {
        cout << "Box cheese pizza" << endl;
    }
};

class PepperoniPizza : public Pizza
{
public:
    void prepare() override
    {
        cout << "Prepare pepperoni pizza" << endl;
    }
    void bake() override
    {
        cout << "Bake pepperoni pizza" << endl;
    }
    void cut() override
    {
        cout << "Cut pepperoni pizza" << endl;
    }
    void box() override
    {
        cout << "Box pepperoni pizza" << endl;
    }
};

class SeafoodPizza : public Pizza
{
public:
    void prepare() override
    {
        cout << "Prepare seafood pizza" << endl;
    }
    void bake() override
    {
        cout << "Bake seafood pizza" << endl;
    }
    void cut() override
    {
        cout << "Cut seafood pizza" << endl;
    }
    void box() override
    {
        cout << "Box seafood pizza" << endl;
    }
};

class PizzaFactory
{
public:
    static Pizza *createPizza(const string &type)
    {
        if (type == "cheese")
        {
            return new CheesePizza();
        }
        else if (type == "pepperoni")
        {
            return new PepperoniPizza();
        }
        else if (type == "seafood")
        {
            return new SeafoodPizza();
        }
        else
        {
            cout << "Unknown pizza type" << endl;
            return nullptr;
        }
    }
};

int main()
{
    string pizzaType;
    cout << "Enter pizza type (cheese/pepperoni/seafood): ";
    cin >> pizzaType;

    Pizza *pizza = PizzaFactory::createPizza(pizzaType);
    if (pizza != nullptr)
    {
        pizza->prepare();
        pizza->bake();
        pizza->cut();
        pizza->box();
        delete pizza;
    }

    return 0;
}
缺点
  • 违反开放-封闭原则(OCP): 当需要新增一种产品时,需要修改工厂类的源代码来添加新的产品类型,这违反了开放-封闭原则。每次修改都会导致工厂类的变化,可能引发其他代码的修改和重新测试,增加了维护成本和风险。

  • 单一职责原则问题: 简单工厂模式中的工厂类负责创建不同类型的产品,导致工厂类的职责不够单一,违反了单一职责原则。随着产品类型的增加,工厂类的代码逐渐变得臃肿,难以维护和理解。

  • 如果需要新增一种产品类型,除了要修改工厂类的代码外,还可能需要修改客户端代码来传递正确的参数类型。这种做法不够灵活,难以应对产品类型的频繁变化。

  • 虽然简单工厂模式封装了对象的创建过程,但它也隐藏了产品的具体创建细节,导致客户端无法直接控制对象的创建过程,无法灵活地定制对象的创建方式。

工厂模式

  • 工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个,也就是说工厂模式让实例化推迟到子类。

在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;

class Pizza
{
public:
    virtual void prepare() = 0;
    virtual void bake() = 0;
    virtual void cut() = 0;
    virtual void box() = 0;
    virtual ~Pizza() {}
};

class CheesePizza : public Pizza
{
public:
    void prepare()
    {
        cout << "Preparing cheese pizza" << endl;
    }
    void bake()
    {
        cout << "Baking cheese pizza" << endl;
    }
    void cut()
    {
        cout << "Cutting cheese pizza" << endl;
    }
    void box()
    {
        cout << "Boxing cheese pizza" << endl;
    }
};

class PepperoniPizza : public Pizza
{
public:
    void prepare()
    {
        cout << "Preparing pepperoni pizza" << endl;
    }
    void bake()
    {
        cout << "Baking pepperoni pizza" << endl;
    }
    void cut()
    {
        cout << "Cutting pepperoni pizza" << endl;
    }
    void box()
    {
        cout << "Boxing pepperoni pizza" << endl;
    }
};

class SeafoodPizza : public Pizza
{
public:
    void prepare()
    {
        cout << "Preparing seafood pizza" << endl;
    }
    void bake()
    {
        cout << "Baking seafood pizza" << endl;
    }
    void cut()
    {
        cout << "Cutting seafood pizza" << endl;
    }
    void box()
    {
        cout << "Boxing seafood pizza" << endl;
    }
};

class PizzaFactory
{
public:
    virtual Pizza *createPizza() = 0;
    virtual ~PizzaFactory() {}
};

class CheesePizzaFactory : public PizzaFactory
{
public:
    Pizza *createPizza() override
    {
        return new CheesePizza();
    }
};

class PepperoniPizzaFactory : public PizzaFactory
{
public:
    Pizza *createPizza() override
    {
        return new PepperoniPizza();
    }
};

class SeafoodPizzaFactory : public PizzaFactory
{
public:
    Pizza *createPizza() override
    {
        return new SeafoodPizza();
    }
};

int main()
{
    string pizzaType;
    cout << "Enter pizza type (cheese/pepperoni/seafood): ";
    cin >> pizzaType;

    PizzaFactory *factory = nullptr;
    if (pizzaType == "cheese")
    {
        factory = new CheesePizzaFactory();
    }
    else if (pizzaType == "pepperoni")
    {
        factory = new PepperoniPizzaFactory();
    }
    else if (pizzaType == "seafood")
    {
        factory = new SeafoodPizzaFactory();
    }
    else
    {
        cout << "Unknown pizza type" << endl;
        return 1;
    }

    Pizza *pizza = factory->createPizza();
    if (pizza != nullptr)
    {
        pizza->prepare();
        pizza->bake();
        pizza->cut();
        pizza->box();
        delete pizza;
    }

    delete factory;

    return 0;
}

抽象工厂模式

抽象工厂的思想是:把有关联关系的,属于一个产品簇的所有产品创建的接口函数,放在一个抽象工厂里面 AbstractFactory,派生类(具体产品的工厂)应该负责创建该产品簇里面所有的产品。

在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;

// 披萨基类
class Pizza
{
public:
    virtual void prepare() = 0;
    virtual void bake() = 0;
    virtual void cut() = 0;
    virtual void box() = 0;
    virtual ~Pizza() {}
};

// 奶酪披萨类
class CheesePizza : public Pizza
{
public:
    void prepare() override
    {
        cout << "Preparing cheese pizza" << endl;
    }
    void bake() override
    {
        cout << "Baking cheese pizza" << endl;
    }
    void cut() override
    {
        cout << "Cutting cheese pizza" << endl;
    }
    void box() override
    {
        cout << "Boxing cheese pizza" << endl;
    }
};

// 香肠披萨类
class PepperoniPizza : public Pizza
{
public:
    void prepare() override
    {
        cout << "Preparing pepperoni pizza" << endl;
    }
    void bake() override
    {
        cout << "Baking pepperoni pizza" << endl;
    }
    void cut() override
    {
        cout << "Cutting pepperoni pizza" << endl;
    }
    void box() override
    {
        cout << "Boxing pepperoni pizza" << endl;
    }
};

// 海鲜披萨类
class SeafoodPizza : public Pizza
{
public:
    void prepare() override
    {
        cout << "Preparing seafood pizza" << endl;
    }
    void bake() override
    {
        cout << "Baking seafood pizza" << endl;
    }
    void cut() override
    {
        cout << "Cutting seafood pizza" << endl;
    }
    void box() override
    {
        cout << "Boxing seafood pizza" << endl;
    }
};

// 汉堡基类
class Hamburger
{
public:
    virtual void prepare() = 0;
    virtual void cook() = 0;
    virtual void cut() = 0;
    virtual void pack() = 0;
    virtual ~Hamburger() {}
};

// 奶酪汉堡类
class CheeseHamburger : public Hamburger
{
public:
    void prepare() override
    {
        cout << "Preparing cheese hamburger" << endl;
    }
    void cook() override
    {
        cout << "Cooking cheese hamburger" << endl;
    }
    void cut() override
    {
        cout << "Cutting cheese hamburger" << endl;
    }
    void pack() override
    {
        cout << "Packing cheese hamburger" << endl;
    }
};

// 香肠汉堡类
class PepperoniHamburger : public Hamburger
{
public:
    void prepare() override
    {
        cout << "Preparing pepperoni hamburger" << endl;
    }
    void cook() override
    {
        cout << "Cooking pepperoni hamburger" << endl;
    }
    void cut() override
    {
        cout << "Cutting pepperoni hamburger" << endl;
    }
    void pack() override
    {
        cout << "Packing pepperoni hamburger" << endl;
    }
};

// 海鲜汉堡类
class SeafoodHamburger : public Hamburger
{
public:
    void prepare() override
    {
        cout << "Preparing seafood hamburger" << endl;
    }
    void cook() override
    {
        cout << "Cooking seafood hamburger" << endl;
    }
    void cut() override
    {
        cout << "Cutting seafood hamburger" << endl;
    }
    void pack() override
    {
        cout << "Packing seafood hamburger" << endl;
    }
};

// 抽象工厂基类
class AbstractFactory
{
public:
    virtual Pizza *createPizza() = 0;
    virtual Hamburger *createHamburger() = 0;
    virtual ~AbstractFactory() {}
};

// 奶酪披萨和奶酪汉堡工厂类
class CheeseFactory : public AbstractFactory
{
public:
    Pizza *createPizza() override
    {
        return new CheesePizza();
    }

    Hamburger *createHamburger() override
    {
        return new CheeseHamburger();
    }
};

// 香肠披萨和香肠汉堡工厂类
class PepperoniFactory : public AbstractFactory
{
public:
    Pizza *createPizza() override
    {
        return new PepperoniPizza();
    }

    Hamburger *createHamburger() override
    {
        return new PepperoniHamburger();
    }
};

// 海鲜披萨和海鲜汉堡工厂类
class SeafoodFactory : public AbstractFactory
{
public:
    Pizza *createPizza() override
    {
        return new SeafoodPizza();
    }

    Hamburger *createHamburger() override
    {
        return new SeafoodHamburger();
    }
};

int main()
{
    string productType;
    cout << "Enter product type (cheese/pepperoni/seafood): ";
    cin >> productType;

    AbstractFactory *factory = nullptr;
    if (productType == "cheese")
    {
        factory = new CheeseFactory();
    }
    else if (productType == "pepperoni")
    {
        factory = new PepperoniFactory();
    }
    else if (productType == "seafood")
    {
        factory = new SeafoodFactory();
    }
    else
    {
        cout << "Unknown product type" << endl;
        return 1;
    }

    Pizza *pizza = factory->createPizza();
    if (pizza != nullptr)
    {
        pizza->prepare();
        pizza->bake();
        pizza->cut();
        pizza->box();
        delete pizza;
    }

    Hamburger *hamburger = factory->createHamburger();
    if (hamburger != nullptr)
    {
        hamburger->prepare();
        hamburger->cook();
        hamburger->cut();
        hamburger->pack();
        delete hamburger;
    }

    delete factory;

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值