Decoratorパターン例（HUNTER×HUNTER クラピカの例）

# 背景
Decoratorパターンって何？デコレーション？美味しいの？
「オブジェクトに対して新たな責務を動的に付加する。
Decoratorによって、サブクラス化による機能拡張よりも柔軟な代替策が実現できる」
意味がわからないので、考えてみました。

# 参考文献
* [増補改訂版 Java言語で学ぶデザインパターン入門](https://www.amazon.co.jp/増補改訂版-Java言語で学ぶデザインパターン入門-結城-浩-ebook/dp/B00I8ATHGW/ref=sr_1_4?__mk_ja_JP=カタカナ&crid=2LX5EGSDGEHES&keywords=デザインパターン&qid=1670657193&sprefix=デザインぱたーn%2Caps%2C350&sr=8-4)

* [オブジェクト指向における再利用のためのデザインパターン](https://www.amazon.co.jp/オブジェクト指向における再利用のためのデザインパターン-エリック-ガンマ/dp/4797311126/ref=sr_1_1?keywords=オブジェクト指向における再利用のためのデザインパターン&qid=1670657488&sprefix=オブジェクト指向における再利用のための%2Caps%2C190&sr=8-1)

* [オブジェクト指向のこころ](https://www.amazon.co.jp/オブジェクト指向のこころ-SOFTWARE-PATTERNS-アラン・シャロウェイ/dp/4621066048/ref=sr_1_1?__mk_ja_JP=カタカナ&crid=36ZXDJPM76WZB&keywords=オブジェクト指向のこころ&qid=1671460633&sprefix=オブジェクト指向のこころ%2Caps%2C310&sr=8-1)

参考記事：
あとから記事を見つけて、これ見たほうがわかりやすかった笑

* [JavaでDecoratorパターン](https://qiita.com/mk777/items/6f463466027939a4b137)

# 題材
Decoratorパターンの本質としては、以下を解決するものとして記載があります。
* 複数の追加機能が存在している。
* 追加機能群が規則に従っているかどうか判らない。
* クライアントに余計なことを考えさせることなく、追加機能を特定の順序で付加する仕組みが必要。
* どの追加機能を使用しているのかをアプリケーション側に意識させたくない。

このサンプルを考えるときの身近な例としては、HUNTER×HUNTERのクラピカvsウヴォーギンの戦いが浮かびました。
クラピカの念能力として、色々使えるけど、鎖の念能力を使う順番とかは決まってないとして、
それらを簡単に呼び分けられたら良いと考えました。

# クラス設計
![Decorator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/67c2727f-b862-dd63-1553-3c23ec4f4c9b.png)

# 実装

* 抽象クラス

```cpp:nennnouryokusha.h
#pragma once
#include <iostream>

class nennnouryokusha{
    public:
        virtual void nennnouryoku();
        nennnouryokusha(){}
        ~nennnouryokusha(){}
};
```
```cpp:nennnouryokusha_decorator.cpp
#include <iostream>
#include "nennouryokusha_decorator.h"

/* Concrete */
void nennnouryokusha_decorator::call_nennnouryoku(){
    mynennnouryokusha->nennnouryoku();
};

```




```cpp:nennouryokusha_decorator.h
#pragma once
#include <iostream>
#include "nennouryokusha.h"

class nennnouryokusha_decorator : public nennnouryokusha {
    private:
        nennnouryokusha* mynennnouryokusha;
    public:
        nennnouryokusha_decorator(nennnouryokusha* _nennnouryokusha) : mynennnouryokusha(_nennnouryokusha){}
        void call_nennnouryoku();
        ~nennnouryokusha_decorator();
};
```




* 具象クラス

```cpp:kurapika.h
#pragma once
#include <iostream>
#include "nennouryokusha.h"

class kurapika : public nennnouryokusha{
    public:
        kurapika(){}
        ~kurapika(){}
};
```

```cpp:kurapika.cpp
#include <iostream>
#include "kurapika.h"

/* Concrete */
void nennnouryokusha::nennnouryoku(){
    std::cout << "emperor time!!\r\n";
}
```
```cpp:chain.h
#pragma once
#include <iostream>
#include "nennouryokusha_decorator.h"

class chain_jail : public nennnouryokusha_decorator {
    public:
        chain_jail(nennnouryokusha* _nennnouryokusha) : nennnouryokusha_decorator(_nennnouryokusha){}
        void nennnouryoku();
        ~chain_jail();
};

class judgement_chain : public nennnouryokusha_decorator {
    public:
        judgement_chain(nennnouryokusha* _nennnouryokusha) : nennnouryokusha_decorator(_nennnouryokusha){}
        void nennnouryoku();
        ~judgement_chain();
};

class steal_chain : public nennnouryokusha_decorator {
    public:
        steal_chain(nennnouryokusha* _nennnouryokusha) : nennnouryokusha_decorator(_nennnouryokusha){}
        void nennnouryoku();
        ~steal_chain();
};
```
```cpp:chain.cpp
#include <iostream>
#include "chain.h"

/* Concrete */
void chain_jail::nennnouryoku(){
    std::cout << "chain_jail\r\n";
    nennnouryokusha_decorator::call_nennnouryoku();
}

void judgement_chain::nennnouryoku(){
    std::cout << "judgement_chain\r\n";
    nennnouryokusha_decorator::call_nennnouryoku();
}

void steal_chain::nennnouryoku(){
    std::cout << "steal_chain\r\n";
    nennnouryokusha_decorator::call_nennnouryoku();
}
```

* メイン
チェーンジェイル、スチールチェーン、ジャッジメントチェーンの順番を入れ替えたkurapika1とkurapika2があります。



```cpp:main.cpp
#include <iostream>
#include "nennouryokusha.h"
#include "kurapika.h"
#include "chain.h"

int main(){
    nennnouryokusha *kurapika1;
    nennnouryokusha *kurapika2;

    /* スチールチェーン→ジャッジメントチェーン→チェーンジェイル */
    kurapika1 = new steal_chain(new judgement_chain(new chain_jail(new kurapika)));
    kurapika1->nennnouryoku();

    std::cout << "\r\n\r\n---test---\r\n\r\n";

    /* チェーンジェイル→スチールチェーン→ジャッジメントチェーン */
    kurapika2 = new chain_jail(new steal_chain(new judgement_chain(new kurapika)));
    kurapika2->nennnouryoku();
}
```

# 実行結果
```sh
Decorator % g++ -o test kurapika.cpp main.cpp chain.cpp nennnouryokusha_decorator.cpp
Decorator % ./test                                                                   
steal_chain
judgement_chain
chain_jail
emperor time!!


---test---

chain_jail
steal_chain
judgement_chain
emperor time!!
Decorator % 

```

# 結論
Decoratorパターンの使い所である、複数の機能がどういう順番で呼び出されるか判らないケースとして、クラピカの絶対時間（エンペラータイム）を題材にDecoratorパターンを作ってみました。


結果、クラピカを題材にしたのは分かりづらかったかもしれない！と思いました。笑
ぼくの大好きなCoCo壱のカレーのほうがわかりやすかったなと。
トッピングとしてパリパリチキン・チキンカツ・ソーセージ・ほうれん草などがあって、合計いくらになるのか？などでDecoratorパターン適用したほうが題材として適切だったような気がします。
ただ、僕のやりたいことは、よく判らないことを身近なものを題材にサンプルを作成する、
なのでそういう意味では目標達成できました。