自分なんぞがオブジェクト指向とはなんぞと語るなんておこがましく、「オブジェクトっぽい話」でいいかなーと思っていたのですが、ブックマークするときに「オブジェクト」でタグ付けてる人がいたので、これはいかんと思い、こっそりタイトルを直しました。
2回目の今回は、まんじゅうをいっぱい作ったり、一気に出したり消したりする方法について書きます。
前回、クラス作ってインスタンスを作ると便利だというところで終わりましたが、便利な点としてはまず、「複数のインスタンスをまとめて操作したり、作ったりすることが簡単にできる」という点があります。どういうことかというと、とりあえず、以下のサンプルを見てみてください。
まんじゅうを一気に作ったり、隠したりすることができます。
これで賞味期限が切れたりしても大丈夫なはずです。
この機能を作れと言われたら、前回の知識だけは結構厳しいのではないでしょうか。ガツガツいっぱいスクリプトを書いて悩んだり、$("div.manju")とかで毎回まんじゅう探してきたりするんじゃないでしょうか。今回は、まんじゅうクラスに加え、まんじゅうマネージャークラスという、まんじゅうを作ったり、まんじゅうに命令を与えるクラスを作ることで、これを実現しています。
なお、まんじゅうもこっそり改良されています。モダンな人にはよりまんじゅうに見えるようになっただけでなく、Manjuクラスもちょっとよさげになっていますので、興味がある方は前回のManjuクラスと見比べてみてください。
これがまんじゅうマネージャークラスのソースです。
/**
* ManjuManager
* まんじゅうマネージャークラス。
*/
var ManjuManager = function(){
this.manjuPool = []; // まんじゅうを貯めておく配列
};
ManjuManager.prototype = {
createManju: function(){
var manju = new Manju(); // まんじゅうを作る
this.manjuPool.push(manju); // まんじゅうプールに入れる
},
createPluralManju: function(num){
// 指定された個数分、createManju()を呼ぶ
for(var i=0,l=num; i<l; i++){
this.createManju();
}
},
showAllManju: function(){
// まんじゅうプールに入ってるまんじゅうそれぞれにつき…
$.each(this.manjuPool, function(){
// showメソッドを呼ぶ
this.show();
});
},
hideAllManju: function(){
// まんじゅうプールに入ってるまんじゅうそれぞれにつき…
$.each(this.manjuPool, function(){
// hideメソッドを呼ぶ
this.hide();
});
}
};
/* まんじゅうマネージャーのインスタンス作成 */
manager = new ManjuManager();
各メソッドの機能は、ざっと説明すると以下のようになります。
用意したサンプルページのボタンを押すとこれらが呼ばれます。
スクリプトの最後のところで、
manager = new ManjuManager();
とやっています。前回、まんじゅうの雛型(クラス)からまんじゅう(インスタンス)を作ったように、このまんじゅうマネージャーも同様、まんじゅうマネージャークラスから、1個だけ、まんじゅうマネージャーを作っています。
この、まんじゅうマネージャー:managerのメソッドを以下のように呼ぶことで、今説明した機能を使うことができます。
manager.createManju();
manager.createPluralManju(3);
manager.showAllManju();
manager.hideAllManju();
このまんじゅうマネージャーのキモは、コンストラクタ内で作られる、まんじゅうプールにあります。
var ManjuManager = function(){
this.manjuPool = []; // まんじゅうを貯めておく配列
};
とりあえず、まんじゅうマネージャーが作られたら、まんじゅうプールが設置されます。まんじゅうを作る、createManjuメソッドの中身をちょっと見てみます。
createManju: function(){
var manju = new Manju(); // まんじゅうを作る
this.manjuPool.push(manju); // まんじゅうプールに入れる
},
newでまんじゅうを作るのは前回と変わりません。そのあと、まんじゅうプールにそのまんじゅうを入れるということを行っています。作られたまんじゅうは、全て、このまんじゅうプールに貯めて置かれるのです。あるクラスのインスタンスの中で、別のクラスのインスタンスを作り、それを保存しておくのです。ちょっとややこしいですね。
まんじゅうを一気に作ることができる、createPluralManjuメソッドも見てみます。
createPluralManju: function(num){
// 指定された個数分、createManju()を呼ぶ
for(var i=0,l=num; i<l; i++){
this.createManju();
}
},
ここでやっていることは、指定された数分だけ、まんじゅうマネージャーのcreateManjuメソッドを呼ぶということを行っています。これでまんじゅうの大量生産もあっという間です。まんじゅうは、createManjuメソッド内で作られるので、作られたまんじゅうはまんじゅうプールに貯められます。はて、こんな複雑なことをしてまでまんじゅうを貯めて、なんか得があるのでしょうかと言うと…
この貯められたまんじゅうに対して色々な操作ができるのです。まんじゅうを一気に消したり出したりする、showAllManju、hideAllManjuメソッドを見てみます。
showAllManju: function(){
// まんじゅうプールに入ってるまんじゅうそれぞれにつき…
$.each(this.manjuPool, function(){
// showメソッドを呼ぶ
this.show();
});
},
hideAllManju: function(){
// まんじゅうプールに入ってるまんじゅうそれぞれにつき…
$.each(this.manjuPool, function(){
// hideメソッドを呼ぶ
this.hide();
});
}
これらは、まんじゅうプールに入っている全てのまんじゅうに対し、showメソッド、hideメソッドを呼ぶというだけの機能になります。$.eachというのは、jQueryの便利機能で、「第一引数の配列の各要素につき…第二引数で指定した関数を実行せよ」ということしてくれます。第二引数で指定した関数の中でのthisは、配列に格納された各要素…まんじゅうインスタンスになります。まんじゅうプールにたまってるまんじゅうそれぞれの出せー隠せーというメソッドを呼んであげています。
まんじゅうマネージャーを介することで、つくられたまんじゅうは、まんじゅうマネージャー内のまんじゅうプールに貯められるので、これらをまとめて、それもごく単純に操作することができるのです。
こんな感じでまんじゅうマネージャーを作ると、Manjuクラスを一切意識せず、managerのメソッドを呼ぶだけで色々なまんじゅうの操作を一気に出来るようになります。まんじゅうマネージャーは、まるで工場のような役割を果たします。1個1個手でまんじゅうを作るよりもはるかに効率的で便利です。まんじゅうの作り方を知らなくても、まんじゅうマネージャーに、まんじゅう作ってと言えば済むようになるのです。産業革命やでこれは・・・。
これを発展させたプログラムの組み方(デザインパターンと言う)に、Abstract Factoryパターン、Flyweightパターンというものがあります。Abstract Factoryパターンは、まんじゅう工場ではなく、お菓子工場を作るようなイメージです。まんじゅうクラスだけでなく、ようかんクラス、もなかクラスなどの沢山のお菓子クラスが存在する場合、効率的にお菓子を作ったり管理したりするための方法になります。Flyweightパターンというのは、今回のように複数のインスタンスを作ってそれをどうこうする時に、共通するデータや機能を、マネージャークラスに持たせて効率化を図るための方法です(スミマセンまんじゅうだといい例が思いつきませんでした)。これらについてもおいおい説明するかもしれないです。それらの中では、今回作ったまんじゅうマネージャーのようなクラスのことを、Factoryクラスとか呼んでいるみたいです(←これあんまり自信なし)。
まーしかし、こう思いませんか?
「ていうかまんじゅう作るプログラムなんて書かないし!」
それには僕も賛成します。「ほう!ではあれもこれもこれでもっと素敵に書けるな」とか頭のキレる人はわずかなんじゃないでしょうか。僕も大して考えずに書いてたらはちゃめちゃになってきてこういうのにたどり着いたので・・・。次回は、実際に使われるような機能を、1回目と2回目で説明した方法で実装してみるサンプルを説明しようかと思います。
続く…(たぶん)
---
【参考】
---
2009/6/19追記
もともと、本文中にFactory Methodパターンと書いてあったのは、Abstract Factoryパターンの間違いだったので修正しました。ブックマークコメントで教えてくださった方ありがとうございます!
This article is about... JavaScript , jQuery , オブジェクト指向
regepan 2011/1/13 (08:26)
まんじゅうマネージャーすげーべんきょうになります。
regepan 2011/1/16 (02:23)
こちらのスクリプトを色々と弄らせて頂いているのですが、
まんじゅうを消す方法で行き詰っています。
まんじゅうって消えますか?