オブジェクト指向っぽくオセロを作る5
- オブジェクト指向っぽくオセロを作る
- オブジェクト指向っぽくオセロを作る2
- オブジェクト指向っぽくオセロを作る3
- オブジェクト指向っぽくオセロを作る4
- オブジェクト指向っぽくオセロを作る6
- オブジェクト指向っぽくオセロを作る7
- オブジェクト指向っぽくオセロを作る8
- オブジェクト指向っぽくオセロを作る9
- オブジェクト指向っぽくオセロを作る10
- オブジェクト指向っぽくオセロを作る(まとめ)
続きです。前回Othelloオブジェクトを作ると書いたのですが、やっぱりやめて、Viewオブジェクトに手を加えてみました。前回ちょろっと書きましたが、Viewオブジェクトは内部に_boardというプロパティを持っています。これを外部から隠したいという話がありました。クロージャのテクニックを使うことで、これを実現します。ただ、ソースが前のものに比べて少し見難くなったかもしれません。なお、処理的にはたいして変化はありませんので、この回を飛ばして、次の内容に進んでもらっても問題ありません。
こんな感じになりました
var View = {}; (function(){ var board; /** * Boardクラスから生成したboardオブジェクトをセットする */ function setBoard(_board){ board = _board; } View.setBoard = setBoard; //外部からアクセスできるようにする /** * boardの情報を実際に盤として描写するための処理 * 変更された箇所のみを再度描写しなおす */ function paint() { if(!board) throw new Error("board is null/undefined. please call setBoard method before paint."); var board_element = document.getElementById("board"); for ( var y = 0; y < 8; y++) { for ( var x = 0; x < 8; x++) { /* * boardオブジェクトが示す駒と * DOM要素が示す盤の駒を比較 * 差異がある場合だけ描写を行う */ var nType; //boardオブジェクトの示す駒の種類 switch ( board.getPiece(x, y) ) { case Piece.BLACK: nType="black"; break; case Piece.WHITE: nType="white"; break; case Piece.EMPTY: nType="empty"; break; } //DOM要素の示す駒を取ってくる var id = "cell" + (x + 1 + y * 8); //idはcell1からcell64まで var bElement = document.getElementById(id); if(bElement){ //一番最初はDOM要素がないのでエラーではない var bType = bElement.className; //classは駒の種類に対応している } //同じなら描写しなおす必要がないので次の周に if(nType && bType == nType) continue; else{ //違うなら if(bElement) //なおかつ現在DOM要素があるなら board_element.removeChild(bElement); //DOM要素を取り除く } //新たに追加するDOM要素を作る var nElement = makeElement(nType, id, x, y); if(nElement){ board_element.appendChild(nElement); } } } } View.paint = paint; //外部からアクセスできるようにする /** * 指定された種類のセルのDOM要素を作成する * typeはblack, white, emptyのいずれか * なお、この関数はpaintメソッド内でのみ有効 */ function makeElement(type,id,x,y){ var element; if(type != "black" && type != "white" && type != "empty"){ throw new Error("illegal argument 'type': "+type); }else{ element = document.getElementById(type).cloneNode(true); if(!element) throw new Error("idが"+type+"のDOM要素をクローンできませんでした。"); } element.style.left = 32 * x + "px"; element.style.top = 32 * y + "px"; element.id = id; return element; } })();
クロージャについての詳しい解説はここではしません。以前書いたクロージャのテクニックに関する記事をご覧下さい。ポイントは、以前this._boardとしていたものをvar boardとして、ローカル変数にしています。これによって外部から直接boardにアクセスできなくなりました。また、setBoardとpaintメソッドは外部から利用できるようにしなくてはいけないので、
View.setBoard = setBoard; //外部からアクセスできるようにする View.paint = paint; //外部からアクセスできるようにする
という風に、ViewのsetBoardプロパティ、paintプロパティから参照しています。またmakeElementメソッドは外部からアクセスする必要がないので、上記のような処理が必要ありません。
次回は「オセロのルール」を表現するOthelloオブジェクトを作ります。