装饰模式,是为了动态的增加一个职责,但是需要是顺序增加的。实现的核心,是通过has-a的方式,是在子类中存储一个父类的指针或者引用,然后再生成该装饰的时候,将父类的地址传入,然后通过父类的多态来实现原来的功能,自己在新的装饰器类中在添加新的功能。
#include <iostream>
#include <memory>
#include <string>
using namespace std;
/* 装饰模式
* 动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活,
* 需要把所需要的功能按正确的顺序串联起来进行控制
*/
class CPhone
{
public:
CPhone() {}
virtual ~CPhone() {};
virtual void Show() = 0;
private:
CPhone& operator=(const CPhone&) = delete;
CPhone(const CPhone&) = delete;
protected:
string m_name;
};
//手机子类
class CIPhone : public CPhone
{
public:
CIPhone(string name)
{
m_name = name;
cout << "CIPhone" << endl;
}
virtual void Show()
{
cout << "CIPhone " << m_name << "的装饰" << endl;
}
};
//手机子类
class CHuaWeiPhone : public CPhone
{
public:
CHuaWeiPhone(string name)
{
m_name = name;
cout << "CHuaWeiPhone" << endl;
}
virtual void Show()
{
cout << "CHuaWeiPhone " << m_name << "的装饰" << endl;
}
};
//挂件
class CDecoratePendant : public CPhone
{
public:
CDecoratePendant(CPhone* phone):
m_phone(phone)
{
}
virtual void Show()
{
m_phone->Show();
cout << "增加挂件" << endl;
}
private:
CPhone* m_phone;//关键,has_a,通过m_phone调用原来的功能,新加的功能通过装饰实现
};
//手机壳
class CDecorateShell : public CPhone
{
public:
CDecorateShell(CPhone* phone)
:m_phone(phone)
{
}
virtual void Show()
{
m_phone->Show();
cout << "增加手机壳" << endl;
this->SetPassword();
}
private:
void SetPassword()
{
cout << "设置密码" << endl;
}
CPhone* m_phone;
};
int main()
{
CPhone* phone1 = new CIPhone("S8");
CDecoratePendant* phone2 = new CDecoratePendant(phone1);
phone2->Show();
CDecorateShell* phone3 = new CDecorateShell(phone2);
phone3->Show();
delete phone3;
delete phone2;
delete phone1;
return 0;
}