package com.objectfanatics.samplecomponent.component { import com.objectfanatics.samplecomponent.controller.Controller; import com.objectfanatics.samplecomponent.controller.ViewAdapter; import com.objectfanatics.samplecomponent.model.Model; import com.objectfanatics.samplecomponent.model.ModelImpl; import com.objectfanatics.samplecomponent.view.ModelListenerImpl; import com.objectfanatics.samplecomponent.view.ViewInitializer; import flash.display.Sprite; import flash.text.TextField; /** * FlashIDE 上の LIBRARY にて、フォルダ名が com.objectfanatics.samplecomponent、名前が Component のシンボルに対応するクラスです。 * * このサンプルでは、GUIコンポーネントという単位を扱い、このクラスが1つの GUI コンポーネントを表しています。 * * このコンポーネントの内部には TextField などの GUI コンポーネントが内包(FlashIDE上で定義されたシンボルのインスタンスやActionScriptで動的に作成されたものなど) * されており、それはこのコンポーネントそのものの Model, View, Controller のいずれでもないと考えます。 * * そのため、このコンポーネントは Model, View, Controller だけでなく、自身を表す Component とその内部の Sub Components で表されると考えます。 * * View については、Model の内容を常に反映しながら情報を外部に提供するという MVC で言うところの View は、オブジェクトとしては存在しないと考えます。 * なぜなら、この役割は自身を表す Component もしくはその内部の Sub Components によって達成されるからです。 * * 自身を表す Component とその内部の Sub Components が View に該当するかというと、View としての性質を持っていますが、同時に Model でもあり Controller でも * あるため、View と表現するのは妥当ではないと考えます。そのため、自身を表す Component とその内部の Sub Components という表現をしています。 * */ public class Component extends Sprite { /** * numberText sub component. */ public var numberText:TextField; public function Component ():void { // Model を初期化します var model:Model = new ModelImpl (); // Model の変更内容を監視し Component に反映させるための ModelListener を初期化します model.modelListener = new ModelListenerImpl (this); // Controller を初期化します var controller:Controller = new Controller (this, model); // Component もしくは Sub Components からの入力を監視し Controller に伝える処理を行うクラスを初期化します new ViewAdapter (this, controller); // View を初期化します new ViewInitializer (this, model); } } }
package com.objectfanatics.samplecomponent.controller { import com.objectfanatics.samplecomponent.component.Component; import com.objectfanatics.samplecomponent.model.Model; /** * Controller クラスです. * * Component の監視処理の記述は ViewAdapter クラスが行っています。 * * Controller 自身が Component や Sub Component の監視を行う場合、複数のコンポーネント上で * ボタンの監視やキーが押されることが、Model の値をインクリメントさせるトリガに成り得ます。 * このような処理を Controller の Component 寄りの処理と言うことにします。 * * しかし、どのボタンが押されてもキーが押されても Controller としては Model の値をインクリメント * して欲しいというイベントであると考えられます。このような考えに基づく処理を Controller の * Model 寄りの処理と言うことにします。 * * そう考えると、Controller の Model 寄りの処理を Controller が、Component 寄りの処理を * ViewAdapter が行っていると言うことができます。 */ public class Controller { private var model:Model; private var component:Component; public function Controller (component:Component, model:Model):void { this.component = component; this.model = model; } /** * Model の値をインクリメントします. */ public function increment ():void { model.increment (); } } }
package com.objectfanatics.samplecomponent.controller { import com.objectfanatics.samplecomponent.component.Component; import flash.events.KeyboardEvent; import flash.events.MouseEvent; import flash.ui.Keyboard; /** * Controller の Component 寄りの処理を受け持つクラスです. * * Component もしくは Sub Components からの入力を監視し Controller に伝える処理を行います. */ public class ViewAdapter { private var controller:Controller; public function ViewAdapter (component:Component, controller:Controller):void { // Controller の格納 this.controller = controller; // Component のクリックの検出設定 component.addEventListener (MouseEvent.CLICK, onClicked); // Enter キーの検出設定 component.addEventListener (KeyboardEvent.KEY_UP, onKeyUp); } private function onClicked (e:MouseEvent):void { controller.increment (); } private function onKeyUp(e:KeyboardEvent):void { if (e.keyCode == Keyboard.ENTER) { controller.increment (); } } } }
package com.objectfanatics.samplecomponent.model { /** * Model インタフェースです. */ public interface Model { /** * ModelListener をセットします。 * @param modelListener ModelListener */ function set modelListener (modelListener:ModelListener):void; /** * 値を返します。 * @return 値 */ function get number ():uint; /** * 値を1増やします。 */ function increment ():void; } }
package com.objectfanatics.samplecomponent.model { /** * Model の実装クラスです. */ public class ModelImpl implements Model { private var _modelListener:ModelListener; /** * 保持される値 */ private var _number:uint = 0; /** * Model#get number():uint の実装 */ public function get number ():uint { return _number; } /** * Model#set modelListener(modelListener:ModelListener):void の実装 */ public function set modelListener (modelListener:ModelListener):void { this._modelListener = modelListener; } /** * Model#increment():void の実装 */ public function increment ():void { this._modelListener.numberChanged (++_number); } } }
package com.objectfanatics.samplecomponent.model { /** * Model の変更内容を監視するためのリスナー */ public interface ModelListener { /** * 値が変更された場合に呼び出されます。 * * @param number 変更後の値 */ function numberChanged (number:uint); } }
package com.objectfanatics.samplecomponent.view { import com.objectfanatics.samplecomponent.component.Component; import com.objectfanatics.samplecomponent.model.ModelListener; /** * Model の変更内容を監視し Component に反映させるための ModelListener の実装クラス。 */ public class ModelListenerImpl implements ModelListener { /** * 変更対象の Component */ private var component:Component; /** * コンストラクタ * @param view 変更対象の View */ public function ModelListenerImpl (component:Component):void { this.component = component; } /** * Model の値が変更された時に呼び出され、View 上の表示を変更します。 * @param currentNumber 現在のの Model の値 */ public function numberChanged (currentNumber:uint) { component.numberText.text = "" + currentNumber; } } }
package com.objectfanatics.samplecomponent.view { import com.objectfanatics.samplecomponent.component.Component; import com.objectfanatics.samplecomponent.model.Model; /** * View を初期化するためのクラスです. * * ここではこのコンポーネント全体の見た目を初期化するため、View ということばをあえて使用しています。 */ public class ViewInitializer { /** * View を初期化します. * * @param component Component * @param model Model */ public function ViewInitializer (component:Component, model:Model):void { component.numberText.text = "" + model.number; } } }
[Fatal Error] :3:6: エレメント型 "Hoge" は対応する終了タグ "</Hoge>" で終了する必要があります。 適格な形式でないテキストが検出されました。詳細については、C:\hoge\fuga\piyo\validation_errors.log を参照してください。
org.xml.sax.SAXParseException: エレメント型 "Hoge" は対応する終了タグ "</Hoge>" で終了する必要があります。