Decorator パターン

Decorator パターン - Wikipedia

オブジェクトにどんどんデコレーションをくっつけていくようなイメージ。実際にはどんどんオブジェクトをかぶせていく。くっつけられていくものは”機能”。以下の例はwikipediaに載って得いたJAVAのコードをC++に書き変えたもの。そこでは

new WholesalePrice(new DoublePrice(new PrimePrice(default_price)), 30);

のように原価(PrimePrice)を二倍(DoublePrice)したものに利益30円を載せて全体の利益(WholesalePrice)としているような計算を実行しているが、このように動的に機能(ここでは価格計算機能)を追加することができるのがうれしい。

#include<iostream>
using namespace std;
//Component
//価格インターフェイス
class Price
{
public :
	virtual int GetValue() = 0;
};
//Concrete Component
//原価クラス
class PrimePrice : public Price
{
public :
	PrimePrice(int value) : value_(value){}
	int GetValue(){
		return this->value_;
	}
private :
	int value_;
};
//Decorator
//価格にマージンのっけるためのクラス
class MarginPrice : public Price
{
public :
	MarginPrice(Price *price) : price_(price){}
	virtual ~MarginPrice(){delete price_;}
protected :
	Price *price_;
};
//Concrete Decorator 1
//価格+利益するクラス
class WholesalePrice : public MarginPrice
{
public :
	WholesalePrice(Price *price, int advantage) : MarginPrice(price), advantage_(advantage){}
	int GetValue(){
		return(this->price_->GetValue() + advantage_);
	}
private :
	int advantage_;
};
//Concrete Decorator 2
//価格×2するクラス
class DoublePrice : public MarginPrice{
public : 
	DoublePrice(Price *price) : MarginPrice(price){}
	int GetValue(){
		return this->price_->GetValue() * 2;
	}
};
//main
int main()
{
	int default_price = 120;
	Price *p1 = new PrimePrice(default_price);
	Price *p2 = new DoublePrice(new PrimePrice(default_price));
	Price *p3 = new WholesalePrice(new PrimePrice(default_price), 30);
	Price *p4 = new WholesalePrice(new DoublePrice(new PrimePrice(default_price)), 30);

	cout << "Default   : " << p1->GetValue() << endl;
	cout << "Double    : " << p2->GetValue() << endl;
	cout << "Wholesale : " << p3->GetValue() << endl;
	cout << "Combine   : " << p4->GetValue() << endl;

	delete p1;
	delete p2;
	delete p3;
	delete p4;

	getchar();
	return 0;
}