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

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


はじめに

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() 


まとめ

関数オブジェクトでの実装だとインターフェースや振る舞いクラスを考えなくていいのは楽ですね。

間違っているところや、「もっと改善できる」という点があればご意見ください。

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)