LoginSignup
4
2

More than 5 years have passed since last update.

Strategyパターンはただの関数オブジェクトなのか?

Last updated at Posted at 2018-11-11

はじめに

Head Firstデザインパターンを読んでデザインパターンの勉強をしています。

また、次のQiita記事
再考: GoF デザインパターン
の中で

Strategy
単なる関数オブジェクトである。

とあるので、C++、JavaScript、Pythonにおいて関数オブジェクトでの実装を考えてみました。
例題は上記書籍のものです。

C++(C++11)の場合

実行環境:Wandbox(gcc 8.2.0)

関数オブジェクトを扱うためにstd::functionを用います。

#include <iostream>
#include <cstdlib>
#include <functional>

class Duck {
    std::function<void(void)> quackBehavior;
public:
    void performQuack() {
        quackBehavior();
    };

    void setQuackBehavior(std::function<void(void)> f) {
        quackBehavior = f;
    };
};

void quack() {
    std::cout << "ガーガー" << std::endl;
}

void muteQuack() {
    std::cout << "<沈黙>" << std::endl;
}

class MallardDuck : public Duck {
public:
    MallardDuck() {
        setQuackBehavior(quack);
    }
};

int main()
{
    Duck *mallard = new MallardDuck();
    mallard->performQuack();
    mallard->setQuackBehavior(muteQuack);
    mallard->performQuack();
}

JavaScript(ES6)の場合

実行環境:Wandbox(Node.js 8.9.0)

JSだと関数も第一級オブジェクトなので、そのまま渡すだけです。

class Duck {
    constructor() {
       let quackBehavior;
    }

    performQuack() {
        this.quackBehavior();
    }

    setQuackBehavior(f) {
        this.quackBehavior = f;
    }
};

const quack = () => {
    console.log("ガーガー");
}

const muteQuack = () => {
        console.log("<沈黙>");
}

class MallardDuck extends Duck {
    constructor() {
        super();
        this.quackBehavior = quack;
    }
};

{
    const mallard = new MallardDuck();
    mallard.performQuack();
    mallard.setQuackBehavior(muteQuack);
    mallard.performQuack();
}

Python(Python3.6の場合)

実行環境:Wandbox(Cpython 3.6.2)

PythonでもJSと同じですね。

class Duck:
    def __init__(self):
        self.quackBehavior

    def performQuack(self):
        self.quackBehavior()

    def setQuackBehavior(self,f):
        self.quackBehavior = f

def quack():
    print("ガーガー")

def muteQuack():
    print("<沈黙>")

class MallardDuck(Duck):
    def __init__(self):
        self.quackBehavior = quack

mallard = MallardDuck()
mallard.performQuack()
mallard.setQuackBehavior(muteQuack)
mallard.performQuack()

まとめ

関数オブジェクトでの実装だとインターフェースや振る舞いクラスを考えなくていいのは楽ですね。
間違っているところや、「もっと改善できる」という点があればご意見ください。

4
2
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
4
2