#はじめに
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()
#まとめ
関数オブジェクトでの実装だとインターフェースや振る舞いクラスを考えなくていいのは楽ですね。
間違っているところや、「もっと改善できる」という点があればご意見ください。