nprogram’s blog

気ままに、プログラミングのトピックについて書いていきます

Strategy Patternについて

[Duch.h]

#include <iostream>
using namespace std;

//QuackBehavior インターフェース
class QuackBehavior
{
public:
    virtual ~QuackBehavior() {}
    virtual void quack() const = 0; //純粋仮想関数(派生クラスに)
};

//QuackBehaviorインターフェースを実装したQuack, Squeak, MuteQuack クラス
class Quack : public QuackBehavior
{
public:
    void quack() const
    {
        cout << "gua-gua" << endl;
    }
};
class Squeak : public QuackBehavior
{
public:
    void quack() const
    {
        cout << "kyu-kyu" << endl;
    }
};

//なにもしない(鳴かない)クラス(Nullオブジェクト)
class MuteQuack : public QuackBehavior
{
public:
    void quack() const
    {
        cout << "<<mute>>" << endl;//何もしていないつもりだが、確認のため、出力する
    }
};

// Duck(基底クラス)と種々の派生クラス
class Duck
{
protected:
    QuackBehavior* q;
public:
    virtual ~Duck() { delete q; };
    //virtual を入れなかったのは、Duckクラス共通の振る舞いだから
    //デフォルトの実装と派生クラス独自の実装を分けたい場合は、virtualを付ける
    void quack() const
    {
        q->quack();
    }
};

class RedHeadDuck : public Duck
{
private:
public:
    RedHeadDuck()
    {
        q = new Quack();
    }
};

class RubberDuck : public Duck
{
private:
public:
    RubberDuck()
    {
        q = new Squeak();
    }
};

class DecoyDuck : public Duck
{
private:
public:
    DecoyDuck()
    {
        q = new MuteQuack();
    }
};

[main.cpp]

#include "Duck.h"

int main(void)
{
    Duck* d1 = new RedHeadDuck();
    Duck* d2 = new DecoyDuck();
    Duck* d3 = new RubberDuck();
    //RedHeadDuck()
    //  //基底クラスにアップキャスト
    //  QuackBehavior* q = new Quack();

    // [オブジェクト] [-> : アロー演算子] [メソッド(引数1..)]
    d1->quack();
    d2->quack();
    d3->quack();
    //  q->quack(); // qはQuackBehavior*型でquackメンバ関数は仮想関数なので、派生クラス(Quack)のquackメンバ関数が動的に実行される。

    delete d1;
    delete d2;
    delete d3;

    return 0;
}

実行結果

Visual Studio CommunityからCtrl + F5を押すと、派生クラスのメソッドに従った振る舞いをします。 f:id:nprogram:20170816112833p:plain