C++设计模式·笔记

常用设计模式

1. 单例模式

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

关键点:

  1. 将构造函数的访问属性设置为private
  2. 提供一个**GetInstance()**静态成员函数,只能供用户访问唯一一个实例
  3. 定义一个静态成员指针,用来供用户获取
  4. 重载 (=)赋值操作符以及拷贝构造函数,并设为private, 避免对象间拷贝、复制
class  A
{
private:
    static A* s_pInstance;

    A()		//构造函数为private
    {
    }

    A(const A&);
    A& operator = (const A& t);

public:
    static A* getInstance()
    {
        return s_pInstance;
    }
}

A* A::s_pInstance = new A;

2. 工厂模式

  • 常使用抽象工厂模式,是简单工厂模式和工厂方法模式的组合
  • 优点:
    1. 抽象工厂模式将产品族的依赖与约束关系放到抽象工厂中,便于管理。
    2. 职责解耦,用户不需要关心一堆自己不关心的细节,由抽象工厂来负责组件的创建。
    3. 切换产品族容易,只需要增加一个具体工厂实现,客户端选择另一个套餐就可以了。
  • 缺点:
    1. 抽象工厂模式类增加的速度很快,有一个产品族就需要增加一个具体工厂实现,比较繁琐。
    2. 产品族难以扩展产品。当产品族中增加一个产品时,抽象工厂接口中需要增加一个函数,对应的所有具体工厂实现都需要修改,修改放大严重。
    3. 抽象工厂并未完全屏蔽创建细节,给出的都是组件。对于这种情况可以结合工厂模式或简单工厂模式一起使用。
#include <iostream>
using namespace std;
  
// 抽象产品类类 Television(电视机类)
class Television
{
public:
    virtual void Show() = 0;
    virtual ~Television(){};//析构函数声明为虚函数,防止内存泄漏
};
 
//具体产品类 HaierTelevision(海尔电视机类)
class HaierTelevision : public Television
{
public:
    void Show()
    {
        cout << "I'm HaierTelevision" << endl;
    }
};

//具体产品类 TCLTelevision(TCL电视机类)
class TCLTelevision : public Television
{
public:
    void Show()
    {
        cout << "I'm TCLTelevision" << endl;
    }
};
 
// 抽象产品类  AirCondition(空调类)
class AirCondition
{
public:
    virtual void Show() = 0;
    virtual ~AirCondition(){};//析构函数声明为虚函数,防止内存泄漏
};

//具体产品类 HairAirCondition(海尔空调类)
class HairAirCondition : public AirCondition
{
public:
    void Show()
    {
        cout << "I'm HairAirCondition" << endl;
    }
};

//具体产品类 TCLAirCondition(TCL空调类)
class TCLAirCondition : public AirCondition
{
public:
    void Show()
    {
        cout << "I'm TCLAirCondition" << endl;
    }
};
 
// 抽象工厂类 EFactory(电器工厂类)
class EFactory
{
public:
    virtual Television* CreateTelevision() = 0;
    virtual AirCondition* CreateAirCondition() = 0;
     virtual ~EFactory(){};//析构函数声明为虚函数,防止内存泄漏
};

//具体工厂类 HairFactory(海尔工厂类)
class HairFactory : public EFactory
{
public:
    Television* CreateTelevision()
    {
        return new HaierTelevision();
    }
 
    AirCondition* CreateAirCondition()
    {
        return new HairAirCondition();
    }
};

//具体工厂类 TCLFactory(TCL工厂类) 
class TCLFactory : public EFactory
{
public:
    Television* CreateTelevision()
    {
        return new TCLTelevision();
    }
 
    AirCondition* CreateAirCondition()
    {
        return new TCLAirCondition();
    }
};
  
int main(int argc, char *argv[])
{
  EFactory *hairFactory = new HairFactory ();/*实例化工厂抽象类*/
  Television *haierTelevision =hairFactory->CreateTelevision();/*实例化产品抽象类*/
  AirCondition *haierAirCondition = hairFactory->CreateAirCondition();
  
  haierTelevision->Show();
  haierAirCondition->Show();
  
  EFactory *tCLFactory = new TCLFactory ();
  Television *tCLTelevision = tCLFactory->CreateTelevision();
  AirCondition *tCLAirCondition = tCLFactory->CreateAirCondition();
  
  tCLTelevision->Show();
  tCLAirCondition->Show();
  
  if (hairFactory != NULL)
  {
    delete hairFactory;
    hairFactory = NULL;
  }
  
  if (haierTelevision != NULL)
  {
    delete haierTelevision;
    haierTelevision= NULL;
  }
  
  if (tCLAirCondition != NULL)
  {
    delete tCLAirCondition;
    tCLAirCondition = NULL;
  }
  
  if (tCLFactory != NULL)
  {
    delete tCLFactory;
    tCLFactory= NULL;
  }
  
  if (tCLTelevision != NULL)
  {
    delete tCLTelevision;
    tCLTelevision = NULL;
  }
  
  if (tCLAirCondition != NULL)
  {
    delete tCLAirCondition;
    tCLAirCondition = NULL;
  }
}

3. 观察者模式

  • 核心思想是1对n
  • 比如,我下班的时候告诉孩子和他妈,我开车要往回走了
    • 孩子妈收到消息后开始做饭
    • 孩子收到消息后,就赶紧收起手机,怕挨揍
  1. 基本写法
// 观察者接口
class ObserverInterface
{
public:
    virtual void dosomething()=0;
    virtual ~ObserverInterface(){}
};

// 被观察者接口
class SubjectInterface
{
public:
    virtual void Add(ObserverInterface* obr)=0;
    virtual void Remove(ObserverInterface* obr)=0;
    virtual void Notify()=0;

    virtual ~SubjectInterface(){}
};

// 我自己
class Me:public SubjectInterface
{
public:
    void Add(ObserverInterface* obr) override
    {
        observers.push_back(obr);
    }

    void Remove(ObserverInterface* obr) override
    {
        auto pos=std::find(observers.begin(),observers.end(),obr);
        if(pos!=observers.end())
        {
            observers.erase(pos);
        }
    }

    void Notify() override
    {
        for(const auto& obs:observers)
        {
            obs->dosomething();
        }
    }

private:
    std::vector<ObserverInterface*> observers;
};

// 孩子妈
class Wife:public ObserverInterface
{
public:
    void dosomething() override
    {
        std::cout<<"老公快回来了,开始做饭"<<std::endl;
    }
};

// 孩子
class Son:public  ObserverInterface
{
public:
    void dosomething() override 
    {
        std::cout<<"爸爸快回来了,不能玩游戏了"<<std::endl;
    }
};

// 实际使用
int main()
{
    Me me;
    ObserverInterface* wife=new Wife;
    ObserverInterface* son=new Son;
    me.Add(wife);
    me.Add(son);

    //下班了 发消息
    me.Notify();

    delete wife;
    delete son;
}
  1. 优化:使用shared_ptr
class ObserverInterface
{
public:
    virtual void dosomething()=0;

    //virtual ~ObserverInterface(){}
};

using pObserverInterface=std::shared_ptr<ObserverInterface>;
class SubjectInterface
{
public:
    virtual void Add(pObserverInterface obr)=0;
    virtual void Remove(pObserverInterface obr)=0;
    virtual void Notify()=0;

    //virtual ~SubjectInterface(){}
};


class Me:public SubjectInterface
{
public:
    void Add(pObserverInterface obr) override
    {
        observers.push_back(obr);
    }

    void Remove(pObserverInterface obr) override
    {
        auto pos=std::find(observers.begin(),observers.end(),obr);
        if(pos!=observers.end())
        {
            observers.erase(pos);
        }
    }

    void Notify() override
    {
        for(const auto& obs:observers)
        {
            obs->dosomething();
        }
    }

private:
    std::vector<pObserverInterface> observers;
};


class Wife:public ObserverInterface
{
public:
    void dosomething() override
    {
        std::cout<<"老公快回来了,开始做饭"<<std::endl;
    }

};

class Son:public  ObserverInterface
{
public:
    void dosomething() override 
    {
        std::cout<<"爸爸快回来了,不能玩游戏了"<<std::endl;
    }
};

int main(){
    Me me;
    auto wife=std::make_shared<Wife>();
    auto son=std::make_shared<Son>();
    me.Add(wife);
    me.Add(son);

    //下班了 发消息
    me.Notify();
}

笔记写完当时没记链接,肯定有很多参考别人的地方,但也确实是自己的整理。谨在此对本文中出现过的所有知识的原创者表示敬意。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木杉1900

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值