2012年3月18日日曜日

シングルコンテキストでの設計方法(4)

Titanium Mobileを使ったアプリ開発において、シングルコンテキストで作る際の工夫の続き、第4回です。です。3つのレベルに分けてJavaScriptを作る、という話でした。今回は、その中のレベル2の作り方を取り上げます。

 

レベル2のJavaScriptに入れるのは、MVCモデルのMに含まれる内容です。適用業務で扱うデータを、種類ごとに分けて作ります。顧客情報、商品情報、販売情報など、情報ごとに分けて別々のJavaScriptとして作ります。それぞれに英字1文字を割り当て、その文字を先頭に入れたファイル名を付けるというルールでした。たとえば「c_customaer.js」のように。どのデータのJavaScriptも、次のような形になります。

// c_customaer.js (レベル2)
(function() {
    // 名前空間を別にするために、cの入れ物を用意する
    bb.c = {};

    // 継続保持させるデータ用の変数(bb.c.を付けなくても動くはずですけど...)
    bb.c.customar = [];
    bb.c.custType = [];

    // 外部からデータにアクセスするための関数
    bb.c.getNameF = function(id) { ... }
    bb.c.addCustomerF = function(name, ... ) { ... }
    bb.c.checkCstmIdF = function(id) { ... }
    // 外部からアクセスされない関数
    function calcYearF(date) { ... }
    // 上記2種類の関数は、別々に分けるのではなく、関係の深いものを近付ける形で混在させる
})();

シングルコンテキストの作り方に沿って、JavaScript全体を、即時関数で作ります。最初に用意するのが、cの入れ物です。ここで作る変数も関数もすべてcに登録しますから、他と名前が重複しないように考える必要はありません。JavaScriptの予約語などと重複しないように注意するだけで済みます。Titanium Mobileで使われている名前は、Titaniumオブジェクトに付けてあるので、同じ名前でも重複扱いにはなりませんね。

続いて、このJavaScript内で使うデータ用変数のうち、値を継続して保持する必要がある変数だけ、bb.c空間に付けます。本来は、変数がどこかで必ず参照されていて、bb.c空間に付けなくても動作するはずなのですが、実際に動かすと、ごく一部の変数だけは消えてしまった様子に。もしかしてと思って付けたら、正常に動きました。自分の使い方が悪いのか、そういう動きが正常なのか、未だに不明です。時間がなかったので、ごく一部の変数だけなんですが、また発生して悩むのは時間の無駄でしょう。仕方がないので、値を継続保持する変数だけは、bb.c空間に付けることにしました。もちろん苦肉の策で、この部分だけは非推奨でお願いしますね。

時間がなかったので、とりあえず動くようにして作業を続けました。そしたら、どの変数で発生したのか忘れてしまって、原因追及ができないでいます。コメントで印を付けておくべきでした。まあ、「急いでるから」とか「時間がないから」と先を急ぐときに起りがちな、残念な失敗の一つでしょう。我ながら情けないです。動いているのを変更して探すのもアレなので、とりあえずこのままかな。

レベル2で作る関数には、外部(レベル2上位層とレベル3)から呼ばれる関数と、即時関数の内部からしか呼ばれない関数に分けられます。外部から呼ばれる関数だけはbb.c空間に付けた形で作り、それ以外を普通の関数(function func_name() { ... })として作ります。これらの関数は、内容を理解しやすいように、関係の深い関数を近くに並べるようにします。外部から呼ばれる関数だけ集めて並べる必要はありません。

 

こうして用意したレベル2のJavaScriptの関数は、レベル2上位層とレベル3のJavaScriptで利用します。bb.c空間に付けてるので、それを付けた形で呼び出すだけです。

// ce_customer_edit.js (レベル3)
(function() {
    bb.ce = {};
    bb.ce.win = bb.createWinF('custm_edit');
    ...

    var cstmId = lblCstmId.text;
    if (bb.c.checkCstmIdF(cstmId)) {
        var strCstmName = bb.c.getNameF(numId);
        ...
    }

    ...
})();

用意した空間名「bb.c.」を関数名の前に付けるだけで、それ以外は普通の関数と同じ使い方です。空間名が短いので、それほど邪魔にならないのが救いでしょうか。「bb.c.」すら書きたくない人は、「var c = bb.c」と作れば、「bb.c.」が短い「c.」に置き換えられます。そもそも「bb」は仕方なく付けている接頭語みたいなもので、「c」だけでも意味が通じますからね。私としては、そこまでやる必要がないと思いますけど。

 

レベル2上位層は、レベル3の関数利用とレベル2の関数公開を混ぜたような作り方になります。レベル2で作った関数を、bb.cなどの空間名付きで用いながら、自分が公開する関数を空間名付きで作ります。レベル2上位層にも重複しない空間名が割り当てられているので、関数名を自由に付けられます。レベル2上位層で作った関数の使い方は、レベル2で作った関数と同じです。

ほどほどの長さになったので、続きは別な投稿にしますね。

0 件のコメント:

コメントを投稿