装饰模式
-
动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活
-
装饰模式的UML图:
例子
抽象构件类、具体构件类
class Phone
{
public:
virtual void Show() = 0;
};
class Iphone :public Phone
{
public:
Iphone(string type)
{
m_type = type;
}
virtual void Show()
{
cout << "这是iPhone-" << m_type << endl;
}
private:
string m_type;
};
class MI :public Phone
{
public:
MI(string type)
{
m_type = type;
}
virtual void Show()
{
cout << "这是MI-" << m_type << endl;
}
private:
string m_type;
};
抽象装饰类、具体装饰类
class DecoratorPhone :public Phone
{
public:
DecoratorPhone(Phone* phone)
{
m_phone = phone;
}
virtual void Show()
{
m_phone->Show();
}
private:
Phone * m_phone;
};
手机加模
class DecoratorPhoneMO :public DecoratorPhone
{
public:
DecoratorPhoneMO(Phone* phone):DecoratorPhone(phone)
{
m_phone = phone;
}
virtual void Show()
{
m_phone->Show();
AddMO();
}
void AddMO()
{
cout << "手机添加模" << endl;
}
private:
Phone* m_phone;
};
手机加壳
class DecoratorPhoneKE :public DecoratorPhone
{
public:
DecoratorPhoneKE(Phone* phone) :DecoratorPhone(phone)
{
m_phone = phone;
}
virtual void Show()
{
m_phone->Show();
AddKE();
}
void AddKE()
{
cout << "手机添加壳" << endl;
}
private:
Phone * m_phone;
};
调用:
int main()
{
Phone* phone = NULL;
DecoratorPhone* decorator = NULL;
phone = new Iphone("plus");
decorator = new DecoratorPhoneKE(phone);
decorator->Show();
phone = new MI("6");
decorator = new DecoratorPhoneMO(phone);
decorator = new DecoratorPhoneKE(decorator);
decorator->Show();
return 0;
}
结果:
- 优点:
(1)对于扩展一个对象的功能,装饰模式比继承更加灵活性,通过一种动态的方式来扩展一个对象的功能。
(2)可以对一个对象进行多次装饰。
(3)具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,原有类库代码无须改变,符合“开闭原则”。
- 缺点:
(1) 使用装饰模式进行系统设计时将产生很多小对象,大量小对象的产生势必会占用更多的系统资源,影响程序的性能。
- 使用场景:
(1) 动态、透明的方式给单个对象添加职责。
(2) 当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式。