问:
现有类 A,如果想对类A进行功能增强,有几种方法?
答:在C++种,常用的3种,分别是:
- 直接修改类A的代码。但是不符合开闭原则
- 使用继承,让派生类B来扩充类A的功能
- 使用关联/组合的方式,让类C包含类A,然后对A进行增强(装饰模式基于此方法)
装饰模式:
装饰模式(Decorator Pattern)是动态的给一个对象添加一些额外的职责,就增加功能来说,此模式比生成子类更为灵活。
特点:
(1) 装饰对象和真实对象有相同的接口。这样客户端对象就能以和真实对象相同的方式和装饰对象交互。
(2) 装饰对象包含一个真实对象的引用(reference)
(3) 装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。
(4) 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。
UML类图:
简单实现代码:
#ifndef DECORATEMODE_H
#define DECORATEMODE_H
#include <iostream>
using namespace std;
class Component
{
public:
virtual void Operation() = 0;
};
/**
* @brief The ConcreteComponent class
* 真实的对象
*/
class ConcreteComponent : public Component
{
public:
void Operation()
{
cout << "具体对象的操作"<<endl;
}
};
/**
* @brief The Decorator class
* 装饰的对象
*/
class Decorator : public Component
{
public:
void setComponent( Component * component)
{
m_component = component;
}
void Operation()
{
cout <<"Decorator::Operation()"<<endl;
if ( nullptr != m_component )
{
m_component->Operation();
}
}
private:
//真实的对象
Component *m_component;
};
class ConcreateDecoratorA : public Decorator
{
public:
void Operation()
{
Decorator::Operation();
m_addedState = "new State";
cout<<"具体装饰对象A的操作"<<m_addedState<<endl;
}
private:
string m_addedState;
};
class ConcreateDecoratorB : public Decorator
{
public:
void Operation()
{
Decorator::Operation();
addedBehavior();
cout<<"具体装饰对象B的操作"<<endl;
}
void addedBehavior()
{
cout<<" ConcreateDecoratorB::addedBehavior() "<<endl;
}
};
#endif // DECORATEMODE_H
客户端调用代码;
#include "decoratemode.h"
int main()
{
ConcreteComponent *c = new ConcreteComponent;
ConcreateDecoratorA *d1 = new ConcreateDecoratorA;
ConcreateDecoratorB *d2 = new ConcreateDecoratorB;
d1->setComponent(c);
d2->setComponent(d1);
d2->Operation();
return 0;
}
《大话设计模式》种小菜的UML图:
《大话设计模式》书中小菜的代码:
#ifndef DRESSUP_H
#define DRESSUP_H
#include <iostream>
using namespace std;
/**
* @brief The Person class
* Person类 (ConcreateComponent)
*/
class Person
{
public:
Person()
{
}
Person(string name)
{
m_name = name;
}
virtual void show()
{
cout<<"装扮的: "<<m_name<<endl;
}
private:
string m_name;
};
/**
* @brief The Finery class
* 服饰类 (Decorator)
*/
class Finery : public Person
{
public:
void Decorate( Person *component)
{
m_component = component;
}
void show()
{
if( m_component != nullptr )
m_component->show();
}
private:
Person *m_component;
};
/**
* @brief The TShirts class
* 具体的服饰类 (ConcreateDecorator)
*/
class TShirts : public Finery
{
public:
void show()
{
cout <<"大T恤"<<endl;
Finery::show();
}
};
class BigTrouser : public Finery
{
public:
void show()
{
cout <<"跨库"<<endl;
Finery::show();
}
};
class Sneakers : public Finery
{
public:
void show()
{
cout <<"破球鞋"<<endl;
Finery::show();
}
};
class Suit : public Finery
{
public:
void show()
{
cout <<"西装"<<endl;
Finery::show();
}
};
class Tie : public Finery
{
public:
void show()
{
cout <<"领带"<<endl;
Finery::show();
}
};
class LeatherShoes : public Finery
{
public:
void show()
{
cout <<"皮鞋"<<endl;
Finery::show();
}
};
#endif // DRESSUP_H
客户端调用代码:
#include "dressup.h"
int main()
{
Person *xc = new Person("小菜");
cout<<"\n第一种装扮"<<endl;
Sneakers *pqx = new Sneakers;
BigTrouser *kk = new BigTrouser;
TShirts *dtx = new TShirts;
pqx->Decorate(xc);
kk->Decorate(pqx);
dtx->Decorate(kk);
dtx->show();
delete dtx;
dtx = nullptr;
delete kk;
kk = nullptr;
delete pqx;
pqx = nullptr;
cout<<"\n第二种装扮"<<endl;
LeatherShoes *px = new LeatherShoes;
Tie *ld = new Tie;
Suit *xz = new Suit;
px->Decorate(xc);
ld->Decorate(px);
xz->Decorate(ld);
xz->show();
delete px;
px = nullptr;
delete ld;
ld = nullptr;
delete xz;
xz = nullptr;
return 0;
}