0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Decoratorパターン例(HUNTER×HUNTER クラピカの例)

Last updated at Posted at 2022-12-19

背景

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

参考文献

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

題材

Decoratorパターンの本質としては、以下を解決するものとして記載があります。

  • 複数の追加機能が存在している。
  • 追加機能群が規則に従っているかどうか判らない。
  • クライアントに余計なことを考えさせることなく、追加機能を特定の順序で付加する仕組みが必要。
  • どの追加機能を使用しているのかをアプリケーション側に意識させたくない。

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

クラス設計

Decorator.png

実装

  • 抽象クラス
nennnouryokusha.h
#pragma once
#include <iostream>

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

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

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();
};
  • 具象クラス
kurapika.h
#pragma once
#include <iostream>
#include "nennouryokusha.h"

class kurapika : public nennnouryokusha{
    public:
        kurapika(){}
        ~kurapika(){}
};
kurapika.cpp
#include <iostream>
#include "kurapika.h"

/* Concrete */
void nennnouryokusha::nennnouryoku(){
    std::cout << "emperor time!!\r\n";
}
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();
};
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があります。
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();
}

実行結果

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パターン適用したほうが題材として適切だったような気がします。
ただ、僕のやりたいことは、よく判らないことを身近なものを題材にサンプルを作成する、
なのでそういう意味では目標達成できました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?