まめージェント

Android, GAE, AngularJSの技術ネタ中心。Twitter: @mame01112

Javascriptでデザインパターン (その6: Strategy)

今回はStrategyパターン。

今回で6つ目のデザインパターンです。使ったことのあるデザインパターンを大分出しつくした感があります・・・。苦笑。

そもそもStrategyパターンとは?

wikipediaによると、"アルゴリズムを実行時に選択することができるデザインパターンである"とのこと。何だか分かるような分からないような。

僕の言葉だと、
・例えばHTTPとHTTPSなど、外から見ると同じインタフェースだけど中身のロジックを切り替える必要のある部分で、柔軟にロジックを切り替えることを可能とするパターン”です。
このパターンは仕様変更があることを前提とした(もしくは不確定なまま進む)アジャイルのプロセスと相性がいいかもですね(実際にそこまで使ったことはない。。)
です。

サンプルコードです。

今回の例は、デザイナ (Designerインスタンス)が仕事中、HTMLで書くべきかプレーンテキストでかくべきか決まってない、というケースだとします。このデザイナさんはHTMLとプレーンテキスト、どちらでも素早く納品できるように(下記の例だとshow()できるように)Strategyパターンを使います。

下記の例だと、Designerのインスタンスを作る時に渡される"HtmlStrategy"と"PlainTextStrategy"に応じて、最終的に吐き出されるアウトプットが異なります。Designerへの引数を変えるだけで内部のロジックが変更されるのが伝わるでしょうか。

キモは、HtmlStrategyとPlainTextStrategyが持つ"show()"というメソッド名が同じ、というところですね。ここが同じなため、各Strategyを使うDesignerは"show()"を知っているだけで済みます。

// Concrete Strategy 1
var HtmlStrategy = function(arg) {
	this.content = arg;
};

HtmlStrategy.prototype = {
	show : function(){
		console.log("<html> " + this.content + "</html>");
	}
};

// Concrete Strategy 2
var PlainTextStrategy = function(arg) {
	this.content = arg;
};

PlainTextStrategy.prototype = {
	show : function(){
		console.log("plain text: " + this.content);
	}
};

// Context
var Designer = function(direction){
	this.Strategy = direction;
};

Designer.prototype = {
	createOutput : function(){
		this.Strategy.show();
	}
};

var htmlDesigner = new Designer(new HtmlStrategy("Create html"));
htmlDesigner.createOutput(); // <html> Create html</html>

var textEditor = new Designer(new PlainTextStrategy("Write plain text down"));
textEditor.createOutput(); // plain text:Write plain text down.

Strategyパターンは以上です!(他のウェブサイトのコードも全く見てないけど、問題ないハズ!)