問:
現有類 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;
}