C++ 设计模式

设计模式

  • 创建型模式
    • 工厂方法模式
    • 抽象工厂模式
    • 单例模式
    • 建造者模式(生成器模式)
    • 原型模式
  • 结构型模式
    • 适配器模式
    • 装饰器
    • 代理模式
    • 外观模式
    • 桥接模式
    • 组合模式(部分--整体模式)
    • 享元模式
  • 行为型模式
    • 策略模式
    • 模板模式
    • 观察者模式
    • 迭代器模式
    • 责任链模式
    • 命令模式
    • 状态模式
    • 备忘录模式(快照模式)
    • 访问者模式
    • 中介者模式
    • 解释器模式

设计模式,依据设计目的分为三种:创建型模式、结构型模式、行为型模式
创建型模式包括:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
结构型模式包括:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式包括:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

创建型模式

工厂方法模式

由自己根据需要直接实例化对象
	OBJ *obj;
	if []
		obj = new obj1();
	else
		obj = new obj2();

抽象工厂模式

由工厂分发对象

	OBJ obj = Factory("xxx");

单例模式

全局仅一个该类型对象,可以在尝试使用时候实例化,也可以程序初始化(编译、程序启动时候)时候实例化

	OBJ::GetInstance();

建造者模式(生成器模式)

某些对象的初始化需要多个步骤完成,可以将它交给一个director来初始化,以此达到统一的代码实现

	O o;
	o.setBuilder(builder)
	o.builder();

原型模式

单纯一个深拷贝

	OBJ obj1
	OBJ obj2(obj1)

结构型模式

适配器模式

没什么好说的,就是将同种功能,但实现方式不同的接口、类按照一致的形态进行编写,达到可以任意切换接口、类的目的

装饰器

实现方式有些类似于回调函数,以完成对所需要增加的属性值一一调用接口增加的目的
C++ 设计模式_第1张图片

	class Parent
	{
		virtual void Fun(void)=0;
	}
	class Product : public Parent{
		void Fun(void) override
		{
			//TODO: pass
		}
	}
	class decorator1: public Parent{
		decorator1(Parent & parent):_parent(parent){};
		void Fun(void) override
		{
			_parent.Fun();
		}
		Parent &_parent;
	}
	class decorator2: public Parent{
		decorator2(Parent & parent):_parent(parent){};
		void Fun(void) override
		{
			_parent.Fun();
		}
		Parent &_parent;
	}

相关代码

代理模式

使用代理服务,隐藏原本的类,可用于团队开发,各自负责各自的部分,也可以使用一个小一点的class暴漏或者分等级暴露接口,减少系统维护难度
下述代码可以使用委托类的Request接口

template<class T>
class Proxy
{
    public:
        Proxy(){};
        Proxy(T* sub){m_sub=sub;}; //代理主题角色中定义了一个真实主题角色对象
        ~Proxy(){delete m_sub;};
        void Request()  //代理主题角色也实现了抽象主题角色的方法
        {
            cout<<"Proxy REQ"<<endl;
            m_sub->Request();//代理主题角色调用 真实角色的业务方法
        }
    private:
        T* m_sub;
};

外观模式

个人觉得比较扯淡的一个模式,好比我们喝水,非要说说喝的是H2O, 明明就是一个接口封装,逐级封装, 貌似刚学代码时候就需要了解的东西,下面是从其他博主那边找的例子
点击调准实例地址

#include 
using namespace std;
//外观模式就是将复杂的子类系统抽象到同一个接口进行管理,
//外界只需要通过此接口与子类系统进行交互,
//而不必要和复杂的子类系统进行交互
class Television //电视机类
{
public:
	void On(){
		cout << "电视机打开" << endl;
	}
	void Off() {
		cout << "电视机关闭" << endl;
	}
};
class Gamemachine //游戏机类
{
public:
	void On() {
		cout << "游戏机打开" << endl;
	}
	void Off() {
		cout << "游戏机关闭" << endl;
	}
};
class Microphone //麦克风类
{
public:
	void On() {
		cout << "麦克风打开" << endl;
	}
	void Off() {
		cout << "麦克风关闭" << endl;
	}
};
class Sound //音响类
{
public:
	void On() {
		cout << "音响打开" << endl;
	}
	void Off() {
		cout << "音响关闭" << endl;
	}
};
class Light //灯类
{
public:
	void On() {
		cout << "灯打开" << endl;
	}
	void Off() {
		cout << "灯关闭" << endl;
	}
};
class DVD //DVD类
{
public:
	void On() {
		cout << "DVD打开" << endl;
	}
	void Off() {
		cout << "DVD关闭" << endl;
	}
};
class Facade
{
public:
	Facade() {
		ds = new   Television;
		yxj = new    Gamemachine;
		mkf = new   Microphone;
		yx = new   Sound;
		d     = new Light;
		dvd  = new DVD;
	}
	void KTVPattern()//KTV模式
	{
		cout << "KTV模式启动中,请稍后!" << endl;
		ds->On();
		d->Off();
		mkf->On();
		yx->On();
		dvd->On();
	}
	void GamePattern() //游戏机模式
	{
		cout << "游戏机模式启动中,请稍后!" << endl;
		ds->On();
		yx->On();
		yxj->On();
	}
	~Facade() {
		delete ds;
		delete yxj;
		delete mkf;
		delete yx;
		delete d;
		delete dvd;
	}
private:
	Television*ds;
	Gamemachine*yxj;
	Microphone*mkf;
	Sound*yx;
	Light*d;
	DVD*dvd;
};
void test() {
	Facade*myFacade = new Facade;
	myFacade->KTVPattern();
	myFacade->GamePattern();
}
void main() {
	test();
}


桥接模式

顾名思义,牵线搭桥。 该模式适用于双发没有从属关系、没有上下级关系的场景。
建立一个桥接类,将两个互不统属的类进行关联调用。
实际场景可以参考各个手机的应用商店功能。
相关代码

组合模式(部分–整体模式)

适用于上下级且能够抽象出一致性的场景中,
比如传销组织的结构,开个玩笑,不过传销组织的确很时候使用组合模式。

class PyramidSale {
	string m_string;
	virtual void add(PyramidSale  *)=0;
}
class Level1 :public PyramidSale 
{
	vector<PyramidSale *> m_vecComp;
	void add(PyramidSale  *) override;
}
class Level12:public PyramidSale 
{
	vector<PyramidSale *> m_vecComp;
	void add(PyramidSale  *) override;
}

int main(void)
{
	PyramidSale *l1 = new Level1();
	PyramidSale *l2_1 = new Level2();
	PyramidSale *l2_2 = new Level2();

	l1->add(l2_1);
	l1->add(l2_2);
}

享元模式

共享资源的一种模式,
由于系统开发环节中,很多资源属于能够被公用的,比如某个图片资源、某个音频资源
如果每个对象使用它的时候加载一次,耗费时间,而且多个对象同时加载同一个资源,又浪费内存资源
争对此,提出享元模式

即:某一大型资源加载时候,先查询享元类(可以理解为一个共享空间),在这个空间内使用hash map对资源进行缓存, 如果不存在, 再从flash中加载资源,否则直接从享元类中获取,节省时间与空间

享元类中可以做一个循环队列,某些长时间不使用的大型资源,可以释放掉。
代码链接

行为型模式

策略模式

与工厂模式一样,所不同的是目的不同,也就是应用场景不同,
工厂模式侧重于实例化对象,
策略模式侧重于类中接口的实现,也就是算法的实现

模板模式

class Leader {
	public:
		void run(void)
		{
			a();
			b();
			c();
		}
		virtual void a()==0;
		virtual void b()==0;
		virtual void c()==0;
}

class OfficClerk : Leader{
	public:
		void a() override
		{

		}
		void b() override
		{

		}
		void c() override
		{

		}
}
int main()
{
	Leader *leader = new OfficClerk ();
	leader->run();
}

观察者模式

其他作者是这么描述的:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新

核心解决方案:回调函数

class Observer {
	public:
		virtual void update()= 0;
}
templete <class T>
class Subject {
	private:
		std::list<T *> _objectServerList;
	public:
		void attach(T *object) {
			_objectServerList.push_back(t);
		}
		void detach(T *object) {
			_objectServerList.remove(t);
		}
		void Notify() {
			for(auto object=_objectServerList.begin();object!=_objectServerList.end();object++)
			{
				(*object)->update();
			}
		}
}

迭代器模式

一种遍历的手段,比如链表就是一种迭代器的表现方式,

责任链模式

还是定义不同的接口、或者对象,来将任务拆分成不同的任务(责任)进行
每个接口、对象完成一部分,达到简化代码的目的

命令模式

核心思想:命令模式的作用是将请求封装为一个对象,将请求的发起者和执行者解耦,支持对请求排队以及撤销和重做。
下例中,将Receiver中的两个请求封装成为了两个对象,然后通过命令来进行执行
声明:代码抄袭自链接, 然后使用模板类实现,增强适应性

#include 
#include 
#include 
#include 
#include 

using namespace std;

// 接受者,作为最底层的调用
class Receiver
{
public:
        void BakeMutton()
        {
                cout<< "烤羊肉"<< endl;
        }

        void BakeChicken()
        {
                cout<< "烤鸡翅"<< endl;
        }
};

// 基类
template <class T>
class Command
{
public:
        Command(T* pstReceiver):m_pstReceiver(pstReceiver)
        {
            cout << "m_pstReceiver" << endl;
        };
        ~Command();
        virtual void Excute() = 0;

// protected:
        T* m_pstReceiver;
};

// 具体类,用于调用接收者
template <class T>
class ConcreteCommandA: public Command<T>
{
public:
        ConcreteCommandA(T* pstReceiver) : Command<T>(pstReceiver)
        {
            
        }
        virtual void Excute()
        {
                cout<< "ConcreteCommandA excuting......"<< endl;
                this->m_pstReceiver->BakeMutton();
        }

};

// 具体类,用于调用接收者
template <class T>
class ConcreteCommandB: public Command<T>
{
public:
        ConcreteCommandB(T* pstReceiver):Command<T>(pstReceiver)
        {

        }
        virtual void Excute()
        {
                cout<< "ConcreteCommandB excuting......"<< endl;
                this->m_pstReceiver->BakeChicken();
        }
};

// 调用者,作为最上层,用于管理具体类的操作,从而对接收者增删
template <class T>
class Invoke
{
public:
        void Add(Command<T>* pstCommand)
        {
                m_vecPstCommand.push_back(pstCommand);
        }
        void Remove(Command<T>* pstCommand)
        {
                m_vecPstCommand.erase(find(m_vecPstCommand.begin(), m_vecPstCommand.end(), pstCommand));
        }
        void RemoveAll()
        {
                m_vecPstCommand.clear();
        }
        void Notify()
        {
                for (typeof(m_vecPstCommand.begin()) it = m_vecPstCommand.begin(); it != m_vecPstCommand.end(); ++it)
                {
                        (*it)->Excute();
                }
        }

private:
        vector<Command<Receiver>*> m_vecPstCommand;
};

int main(int argc, char* argv[])
{
        Receiver* pstReceiver = new Receiver();
        Command<Receiver>* pstConcreteCommandA = new ConcreteCommandA<Receiver>(pstReceiver);
        Command<Receiver>* pstConcreteCommandB = new ConcreteCommandB<Receiver>(pstReceiver);
        Invoke<Receiver>* pstInvoke = new Invoke<Receiver>();

        pstInvoke->Add(pstConcreteCommandA);
        pstInvoke->Add(pstConcreteCommandA);
        pstInvoke->Add(pstConcreteCommandB);
        pstInvoke->Notify();
        cout<< "------------------"<< endl<< endl;

        pstInvoke->Remove(pstConcreteCommandA);  //撤销操作
        pstInvoke->Remove(pstConcreteCommandB);
        pstInvoke->Notify();
        cout<< "------------------"<< endl<< endl;

        return 0;
}

状态模式

主要目的是处理状态机之类的事务, 将每个状态封装成为一个单独的类,再借由一个上下文类将所有状态管理起来,每个状态可以借由上下文类切换到其他状态
C++ 设计模式_第2张图片

备忘录模式(快照模式)

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态
个人觉得这个没有什么好聊的,无非就是建立一个管理者类,自己制定好规则,在什么时候将需要备份的类复制进管理者中,在需要的时候拷贝出来就可以完成恢复

访问者模式

有些复杂,还没看懂

中介者模式

该模式提出的设想在于:使用一个中介者来管理所有客户,使得他们能够互相通信,由客户1 改变 客户2 或者客户3 的状态
解除了代码上存在的耦合性
依然抄袭代码,改为模板方式以增加适配性

#include 
#include 

using namespace std;

class Colleague;

//定义一个中介者接口,包含对象改变所需调用函数。
template <class T>
class Mediator
{
public :
    virtual ~Mediator()
    {

    }
    virtual void changed(T *)=0;

protected:
    std::list<T *> _colleague;

};

//定义"同事"类接口,初始化需要一个中介者对象,并通过该类更新另外一个"同事"
class Colleague
{
public :
    //初始化中介者类对象
    Colleague(Mediator<Colleague> * mediator)
    {
        this->mediator =mediator;
    }
    //更新另外一个类
    virtual void changed()
    {
        mediator->changed(this);
    }
    virtual void update()=0;
private:
    Mediator<Colleague> *mediator;
};

//具体的同事类1
class ConcreteColleague1 :public Colleague
{
public:
    ConcreteColleague1(Mediator<Colleague> * mediator):Colleague(mediator)
    {
    }
    void update()
    {
        cout<<"update ConcreteColleague1 from ConcreteColleague2"<<endl;
    }
};
//具体的同事类2
class ConcreteColleague2 :public Colleague
{
public :
    ConcreteColleague2(Mediator<Colleague> * mediator):Colleague(mediator)
    {
    }
    void update()
    {
        cout<<"update ConcreteColleague2 from ConcreteColleague"<<endl;
    }
};

//具体的中介者类,实现更新函数changed。
class ConcreteMediator :public Mediator<Colleague>
{
public:
    void setColleague(Colleague * colleague)
    {
        this->_colleague.push_back(colleague);
    }
    ConcreteMediator()
    {
        //colleague1 = new ConcreteColleague(this);

    }
    ~ConcreteMediator()
    {

    }
    virtual void changed(Colleague* colleague)
    {
        for(auto begin=this->_colleague.begin(); begin!=this->_colleague.end(); begin++)
        {
            if(*begin != colleague)
            {
                (*begin)->update();
            }
        }
    }

};
main()
{
    ConcreteMediator concreteMediator;
    ConcreteColleague1  colleague1(&concreteMediator);
    ConcreteColleague2  colleague2(&concreteMediator);
    concreteMediator.setColleague(&colleague1);
    concreteMediator.setColleague(&colleague2);
    //"同事1"通过中介者更新"同事2"
    colleague1.changed();
    //"同事2"通过中介者更新"同事1"
    colleague2.changed();

}

解释器模式

这个代码是真不会写,csdn上看到的一些解释器的代码,我不觉得有太高的学习价值。
它主要是一个文本分析器,将语法规则设置进去之后,可以分析一段文本的含义。

你可能感兴趣的:(设计模式,c++,设计模式,单例模式)