のんびりしているエンジニアの日記

ソフトウェアなどのエンジニア的な何かを書きます。

DesignPattern Decorator(まるでトッピング)

Sponsored Links

皆さんこんにちは
お元気ですか。良いコードってなんだろう。

今日はDecoratorと呼ばれるデザインパターンを紹介したいと思います。

Decoratorとは

イメージとして基底があって上にのっていくイメージ
機能を追加していくのに便利なデザインパターンですね。

クラス図

f:id:tereka:20140629210349p:plain

実装

ソースコード

#include <iostream>
#include <string>

using namespace std;

//基底クラス
class Pizza{
public:
	virtual string getPizzaName() = 0;
	virtual string getTopping() = 0;
};

//ピザに乗せる大元のピザ
class CheesePizza:public Pizza{
public:
	virtual string getPizzaName();
	virtual string getTopping();
};

string CheesePizza::getPizzaName(){
	return "チーズがのるピザ";
}

string CheesePizza::getTopping(){
	return "うまい味";
}

//スパイシートッピング
class SpicyToppingPizza:public Pizza{
private:
	Pizza *t_pizza;
public:
	SpicyToppingPizza(Pizza *pizza);
	virtual string getPizzaName();
	virtual string getTopping();
};

SpicyToppingPizza::SpicyToppingPizza(Pizza *pizza){
	t_pizza = pizza;
}

string SpicyToppingPizza::getPizzaName(){
	string name = "スパイスがのり";
	name += t_pizza->getPizzaName();
	return name;
}

string SpicyToppingPizza::getTopping(){
	string topping = "辛くて";
	topping += t_pizza->getTopping();
	return topping;
}

//バジルのっけちゃったピザ
class BitterToppingPizza:public Pizza{
private:
	Pizza *t_pizza;
public:
	BitterToppingPizza(Pizza *pizza);
	virtual string getPizzaName();
	virtual string getTopping();
};

BitterToppingPizza::BitterToppingPizza(Pizza *pizza){
	t_pizza = pizza;
}

string BitterToppingPizza::getPizzaName(){
	string name = "バジルがのり";
	name += t_pizza->getPizzaName();
	return name;
}

string BitterToppingPizza::getTopping(){
	string topping = "苦くて";
	topping += t_pizza->getTopping();
	return topping;
}

int main(int argc, char const *argv[]){
        //バジルがのったピザ
	Pizza *pizza1 = new BitterToppingPizza(new CheesePizza());
	cout << pizza1->getPizzaName() << endl;
	cout << pizza1->getTopping() << endl;

       //スパイシーなピザ
	Pizza *pizza2 = new SpicyToppingPizza(new CheesePizza());
	cout << pizza2->getPizzaName() << endl;
	cout <<pizza2->getTopping() << endl;

       //どっちも載せたピザ
	Pizza *pizza3 = new SpicyToppingPizza(new BitterToppingPizza(new CheesePizza()));
	cout << pizza3->getPizzaName() << endl;
	cout << pizza3->getTopping() << endl;

	return 0;
}

出力結果

バジルがのりチーズがのるピザ
苦くてうまい味
スパイスがのりチーズがのるピザ
辛くてうまい味
スパイスがのりバジルがのりチーズがのるピザ
辛くて苦くてうまい味

解説

基底クラスとしてPizzaを用意し
2つのパターンの実装を行います
1つ目はトッピングするベースとなるピザ
2つ目はピザの上に載せるトッピングです。

2つ目のメソッドの内部に別のトッピングのピザを保存し、それらのメソッドを呼び出し、付け加えるような処理を行っております。