【JavaScript】デザインパターンを知ってみる。ファクトリ編
つい最近、横山光輝『三国志』を全60巻読破したminamiです。
今回はJavaScriptで書くファクトリ(Factory)について調べてみました。Factoryはそのまま「工場」の意味です。
なぜ使うのか?
ファクトリの目的はその名の通り、オブジェクトを作成することです。
ポイントとは、共通の親オブジェクトを継承し、個別の機能を専門の静的メソッドに実装する点です。
言葉ではわかりにくいので車のオブジェクトをを作るファクトリを実装してみます。
// 親オブジェクトのコンストラクタ
var CarMaker = function() {
};
// 親オブジェクトのメソッド
CarMaker.prototype.drive = function() {
// 走るとガソリンが減る
this.gas = this.gas - 20;
if(this.gas > 0) {
console.log('ぶーん ' + this.speed +'km で走るよ');
console.log('残りのガソリンは ' + this.gas +'L だよ');
} else {
console.log('ガス欠だよ');
}
};
// ファクトリメソッド(静的メソッド)
CarMaker.factory = function(type) {
var constr = type;
var newcar;
// コンストラクタがない場合はエラー
if(typeof CarMaker[constr] !== 'function') {
throw {
name: 'Error',
message: constr + 'は存在しません'
};
}
// 親から継承
CarMaker[constr].prototype = new CarMaker();
// 新しいインスタンスの作成
newcar = new CarMaker[constr]();
return newcar;
};
// 車の種類を定義
CarMaker.LIGHT = function() {
this.speed = 80;
this.gas = 50;
};
CarMaker.STANDARD = function() {
this.speed = 100;
this.gas = 70;
};
CarMaker.FORMURA1 = function() {
this.speed = 350;
this.gas = 150;
};
// CarMaker オブジェクトを作成する
var lightCar = CarMaker.factory('LIGHT');
lightCar.drive();
lightCar.drive();
lightCar.drive();
var standardCar = CarMaker.factory('STANDARD');
standardCar.drive();
var F1Car = CarMaker.factory('FORMURA1');
F1Car.drive();
実行結果は下記のようになります。
// lightCar
ぶーん 80km で走るよ
残りのガソリンは 30L だよ
ぶーん 80km で走るよ
残りのガソリンは 10L だよ
ガス欠だよ
// standardCar
ぶーん 100km で走るよ
残りのガソリンは 50L だよ
// F1Car
ぶーん 350km で走るよ
残りのガソリンは 130L だよ
上記のファクトリメソッドCarMaker.factory() では、単純に新しくCarMakerオブジェクトを作成して返すだけの処理を行っています。車種による性能やプロパティの違いは全てCarMakerの静的メソッドで定義されています。
よく似ていますが、ファクトリメソッドパターンというパターンもあります。こちらは生成するオブジェクトごとにファクトリを用意して、より柔軟にオブジェクトを作成することができます。上記では同じ工場の別々のラインで軽自動車、普通車、F1カーを作っていましたが、軽自動車工場、普通車工場、F1工場をそれぞれ作って車を作るイメージです。
まとめ
設定や入力値によって様々なオブジェクトを返さなくてはならない場合など、役に立つ場面はいろいろとありそうです。