No.5 Senchaにおけるデザインパターン
Sencha フレームワークの中では、prototype型のオブジェクト指向言語であるJavaScriptに、 伝統的な「クラス」型のオブジェクト指向開発の優れた部分を取り入れたフレームワークとなっています。
クラスを使う利点はいくつかありますが、次のようなものが挙げられるでしょうか。
- チームによる大規模な開発に適切
- クラスのカプセル化、継承、等による再利用・拡張
- 各種デザインパターンの再利用
このような利点のあるクラスの概念を利用するために、
Senchaフレームワークでは自前のクラスシステムを構築しています。
ユーティリティクラスの回に、Ext.define()
とExt.create()
について軽く触れました。
この二つのメソッドを使って、クラスの定義やインスタンスの生成ができます。
そして、このクラスして無を利用して、Senchaフレームワークではオブジェクト指向プログラミングで多用されるいくつかのデザインパターンを利用しています。
利用されるデザインパターンの例
Observable
Senchaフレームワークの全体で使われるイベントモデルにおいて、このObservableパターンが使われています。 Observableなクラスは、そのオブジェクトでイベントを発火することができ、オブジェクトのイベントをリッスンすることができます。 Ext JSではExt.util.Observable、Touchでは、Ext.mixin.Observable クラスがこの責務を担っています。
1 | fireEvent('click', this) |
1 2 3 | button.on('click', function(button) { console.log('clicked'); }) |
イベントモデルについての詳細は、のちほど回を分けて詳しく解説します。
Flyweight
Flywaightパターンは、同じようなインスタンスをそれぞれに生成するのではなく、一つのインスタンスを使い回すやり方です。
前回のDOM操作でお話しした、Elementオブジェクトを取得するために使われる、Ext.fly()
メソッドでこのデザインパターンが使われています。
Singleton
オブジェクトのインスタンスが一つであることを保証するというものです。 Senchaフレームワークのクラスシステムでは、このデザインパターンを使ったSingletonオブジェクトを生成する方法が用意されており、フレームワークの中のいくつかの場所でSingletonクラスが作られています。 APIドキュメントのクラスツリーの中で、赤い色をしたアイコンのクラスはSingletonクラスです。
自分が作成するクラスをシングルトンにすることもできます。 その際には、クラス定義にただ1行加えるだけです。
1 | singleton: true |
Composite
Compositeパターンは、ディレクトリ構造などのツリー上の構造を表現するときによく使われます。 単一のオブジェクトも複数のオブジェクトにも、同じインターフェースを実装します。 Ext.selectの戻り値である、Ext.CompositeElementオブジェクトは、このCompositeパターンを利用しています。 Ext.CompositeElementオブジェクトのメソッドは、Ext.Elementと共通で、 Ext.CompositeElementのメソッドを呼び出すと、そこに格納された全てのDOMに対して、処理されます。
MVCアーキテクチャー
いわゆるGoFパターンとは違いますが、アプリケーションのアーキテクチャを構成するあまりに有名なパターンです。 SenchaフレームワークではこのMVCアーキテクチャーを採用しています。
MVCアーキテクチャーでは、プログラムを3つの要素、Model(モデル)、View(ビュー)、Controller(コントローラ)に分割します。
Model
アプリケーションが扱うデータと手続き(ビジネスロジック)を表現します。 また、データの変更をviewに通知するのもmodelの責任です。 Ext JS 4 のクラスでは、ModelとStoreがこの要素を構成します。
View
modelのデータを取り出してユーザに表示する要素です。すなわちUIへの出力を担当します。 Ext JS 4 のクラスでは多くのコンポーネントでこの要素を構成します。
Controller
ユーザの入力やデータの変更などのイベントに応答し、それを処理する要素です。 Sencha フレームワークでは、Ext.app.Controllerクラスがこの要素を構成します。 Ext.app.Controllerクラスには、Viewのコンポーネントや、Modelのストアなどにイベントリスナーを設定する機能があります。 またリスナーを設定するためにコンポーネントを参照する機能も備わっています。
フォルダ構成
MVCアーキテクチャーに則った、Sencha アプリケーションのフォルダ構造については、導入のページで紹介しました。基本的にはクラス名とそのディレクトリ上の場所は一致しています。
app: appディレクトリ以下にアプリケーションの要素を配置します。上図のそれぞれの要素は、このディレクトリ以下にディレクトリを作って配置されます。
Model: Modelクラスをこのフォルダに配置します。
- View: Viewをこのフォルダに配置します。
- Controller: Controllerクラスをこのフォルダに配置します。
- Store: Storeクラスをこのフォルダに配置します。
名付け規則
SenchaのMVCではいくつかの名付け規則があります。
- 1ファイルに1クラス定義だけをいれます。
- 名前空間はディレクトリ名、クラス名をファイル名とする。
- クラス名の頭文字は大文字。複数単語からなるクラス名はアッパーキャメルケース
- トップレベルの名前空間(例:MyApp)についてはキャメルケースとするが、その他の名前空間は全て小文字とする。
- 頭文字を使った略語であっても、クラス名に使う場合はキャメルケースとする(例:HTTPではなくHttp)
アプリケーションの起動
アプリケーションの起動プロセスには3つのフェーズがあり、そのうちの2つはコントローラーにあります。 init()
メソッドとonLaunch()
メソッド (Touchではlaunch()
メソッド、以下単にonLaunchと表記します)です。
まず、各コントローラーのinit()
メソッドがApplicationのlaunch()
メソッドの前に呼び出されます。
次に、Applicationのlaunch()
メソッドが呼び出され、
最後にコントローラーのonLaunch()
メソッドが呼び出されます。
ほとんどの場合、コントローラー特有の起動ロジックは、コントローラーのonLaunch()
メソッドに記述します。
このメソッドはApplicationのlaunch()
メソッドの後で呼び出されるので、 この時点では、すでにアプリケーションのUIは構成されているからです。
コントローラー特有の処理で、アプリケーションの起動前に実行すべきものがあれば、 init()
メソッドに記述します。
Ext JSにおいては、通常コントローラーでリスナーを設定する、control
メソッドの呼び出しは、init()
メソッドで行います。
ちょっと今回はむずかしかったでしょうか。 こうした既存の様々なデザインパターンを利用して、Senchaのフレームワークは組み立てられていることを覚えておいてください。
次回は、 コンポーネントモデルについてお話しします。