[AS][自分用]ActionScript3.0デザインパターンの読書メモ(7)
-プロキシパターン

プログラムのタスク処理における一般的なやりかた。
他のオブジェクトへのアクセスを提供するためのクラス。
(他のオブジェクト:AS、img、xml、flv、FMS等)
最初にオブジェクトを全部作ってしまうのではなく、必要なときに作ろうという考え方。

仮想プロキシとリモートプロキシの2種類ある。

仮想プロキシ
Loaderクラスがまさにそれ。
プロキシという考え方があるから、画像を読み込みの際、読み込みが完了する前にLoaderのプロパティとか変更できるということらしい。

こんな感じか

//インスタンス生成
var loader:Loader = new Loader();
//loaderインスタンスにはまだ中身は無いけどプロパティとか設定しておく
loader.x = 100;
loader.y = 200;
loader.alpha = 0.5;
//表示リストに追加しちゃっておいても良い
this.addChild(loader);
//そして以下、欲しいときにload()メソッドを実行すればいい、みたいな感じ?

他に仮想プロキシの役割として、ゆるいシリアル化
ゆるいシリアル化の例(XMLの項目を
→硬いシリアル化:xmlを最初に全部要素、属性ごとに配列とかに割り振っちゃう
→ゆるいシリアル化:必要なときに応じて、都度xmlを取り出して使う

リモートプロキシ
対象がネットワーク先になるような感じ。
たとえばflikrAPIをたたいてAPIのメソッドに従った画像ひっぱってくるときの場合、みたいな

[AS]インターフェイスで関数を定義する際、および実装する際は戻り値が必須

インターフェイスで関数を定義する際は戻り値が必須らしい。
(戻り値がない場合も必ずvoidを書かないと駄目っぽい)

たとえばこれだとエラーになった。

package  {
	public interface TestInterface {
		
		//↓戻り値のvoidを省略すると駄目っぽい
		function testFunc1();
		//↓これはOK
		function testFunc2():void;
		function testFunc3():Boolean;
	}
}

また実装の際にもInterfaceで定義された関数を記述する際もvoidの記述が必須。
(省略したらエラーになった)

たとえばこんな感じ。

package  {
	public class Jissou implements TestInterface{
		
		public function Jissou() {
			
		}
		//↓voidを省略するとエラー
		public function testFunc1() {
			trace("testFunc1");
		}
		//これならOK
		public function testFunc2():void {
			trace("testFunc2");
		}
		public function testFunc3():Boolean {
			var bol:Boolean = false;
			return bol;
		}
	}
}

[AS][自分用]ActionScript3.0デザインパターンの読書メモ(5)
-シングルトンパターン

シングルトンのルール
・(シングルトンインスタンスは)プライベートなstaticなプロパティに保持
・(シングルトンインスタンスに)アクセスするにはパブリックなメソッドを使う。(インスタンスが無い場合は生成)

汎用的なシングルトンパターン

package  {
	public class Singleton {
		
		//Singletonインスタンスを保持
		static private var _instance:Settings;
		
		//他のオブジェクトからnew Singleton()では作らせないようにする
		public function Singleton(enforcer:SingletonEnforcer) {
		}
		
		//インスタンス作成はこのメソッドで
		public function getInstance():Settings {
			//一回目はインスタンスを作る
			if (Settings._instance == null){
				Settings._instance = new Settings(new SingletonEnforcer));
				
			}
			//保持しているインスタンスを返す
			return Settings._instance;
		}
	}
}
//new Singletonさせないためのクラス
class SingletonEnforcer{}

[AS][自分用]ActionScript3.0デザインパターンの読書メモ(4)
-MVCモデル

アプリは、UI、ビジネスロジック、データモデルを持つ
→一般的なUIは、リスト、コンボボックス(クリック領域、スクロール領域)を持ち、
→ビジネスロジックは、入力にたいしてどのような処理、どんなデータモデルなのか知っている。

データとインターフェイスの分離に失敗すると
→オブジェクトを外部から利用しがたくなる(データを保持する形の入力フォームは駄目)
→UI変更が容易でなくなる(いろんな形のグラフ作成)
→同一データの多重同時参照が困難(表示携帯ごとにデータのコピー要)
→データの同期が困難(表示携帯ごとに処理わけが必要になる)

★モデル
ビューや、コントローラーから独立して存在できる格納庫。
→文字のような、プリミティブなデータを保持するが、複雑なデータ構造ももてる。
モデルはビューやコントローラーへの参照を持つことはない。
→モデルの柔軟性を保つという重要概念

★ビュー
UIサブシステムの視覚部分
→アニメーション、入力フォーム、チャート、ボタン、オーディオプレイヤーに不可欠なUI要素から構成
ポイント:視覚的な要素、モデルデータを読み取るロジック、UIの要求を処理する、これらで構成される

★コントローラー
入力処理を行う。
モデルやビューの更新もここで行う。

それぞれ(サブシステム)の関係性
モデルは他の要素の情報を持たないが、情報をブロードキャストはする
→ひとつのモデルは複数のビューから参照されることが可能
ビューはモデル情報を持ち、モデルから情報を受信し、モデル情報を読み取ることが可能
→モデルに何かを書き込むということはないが、すべてのビューはモデルへの参照を持つ
コントローラーもモデルにアクセス可能
→ユーザー入力、もしくはシステムイベントでモデルのデータを変更する役割を持つ

コントローラーとビューの関係は密接
ひとつのコントローラーが複数のビューを制御するのは一般的ではない
コントローラーとビューの関係性は1対1が望ましい
ただし、ASではコントローラーとビューをまとめてクラス化することが多い。(ドキュメントビュー実装)
モデルは独立したもので、ビューやコントローラーへの参照は持たない。
ビューはモデルデータの変更を描画に反映

[AS][自分用]ActionScript3.0デザインパターンの読書メモ(3)
-ポリモーフィズム

ポリモーフィズムとは、同一インターフェースを持つ、実装部分が微妙に異なるクラス。
時計でいったら、デジタル時計とアナログ時計における表示部分の実装。

[AS][自分用]ActionScript3.0デザインパターンの読書メモ(2)
-インターフェイス

インターフェイスで定義するメソッドは、パブリックメソッドのみ
(修飾詞は指定できない。privateとか)
パブリックメソッドにはgetter/setterも含む。

インターフェイス

package  {
	public interface IPlus {
                //myPlus関数定義
		function myPlus(number1:Number , number2:Number):Number;
                //ゲッターを定義
		function get myNumber():Number;
		//function set myNumber(value:Number):void;
	}
	
}

クラス

//IPlusを実装したクラス
package  {
	
	public class Plus implements IPlus  {
		private var _myNumber:Number;
		public function Plus() {
			var num1:Number = 10;
			var num2:Number = 5;
			_myNumber = 10;
			
			trace(myPlus(myNumber, num2));
			
		}
		//myPlus関数が無いとエラー
		public function myPlus(num1:Number, num2:Number):Number{
			return num1 + num2;
		}
                //get myNumber()ゲッターが無いとエラー
		public function get myNumber():Number { return _myNumber; }
	}
}

また継承することでもインターフェースも受け継がれる。(実装も継承される)
その際は抽象クラスという概念を持ったクラスを利用する。
抽象クラスはインスタンスを持てないクラスという意味。
ただしAS3では抽象クラスを管理するルールがないので自分で管理する。

[AS][自分用]ActionScript3.0デザインパターンの読書メモ(1)

書籍:ActionScript3.0デザインパターンを読みながらのメモ(自分用)

1.分析フェーズ
→ユースケース作成(フォーマルユースケース)
→→主アクター、事前条件、基本経路、代替経路、特殊用件、検討事項

例)flickrAPIによる検索を使ったスライドショー
◆主アクター:
エンドユーザー
◆事前条件:
エンドユーザーは検索テキストボックス、送信、早送り、巻き戻しボタンの付いた画面を見ている
◆基本経路:
1.検索ワードを入力
2.送信ボタンをクリック
3.flickrがxmlを返す
4.xmlから画像を表示する
◆代替経路
3a.flickrAPIに接続できないときはエラーを表示
4a.検索結果でxmlが空っぽの場合は仮画像を表示
4b.画像の幅が規定サイズより小さい場合は拡大して表示
◆特殊要件
マウス操作以外にキーボードのみでの操作も可能とする
◆検討事項
ローディング処理方法

2.設計フェーズ
→CRCカード作成(Calss:クラス Responsibility:債務 Collaborator:コラボ)
→→クラスに債務を設定したら、当てはまるコラボ(当てはまるクラス)を設定
→クラス関係の精査:関連、集約、継承
→→関連:依存(uses)関係(MAPとMAPDATA)
→→集約:所有(has a)関係(MAPとSTREET)
→→継承:一般的な継承(is a)の概念→ポリモーフィズム
→パブリックAPIの書式を決める:債務のpublic,privateの割り振り

3.実装フェーズ
→コーディング規約の確認(俺流の設定)
→→ローカル変数名の先頭文字にはアンダースコア
→カプセル化:クラスをブラックボックス化するという考え方
→→パブリックなプロパティを使わない
→→→アクセサメソッドを使う
→→外部クラスのオブジェクトを直接参照しない
→→→そのクラスの引数を経由した参照は除く
→→→(駄目な使い方の例がないので、よくわからない p20)
→→配列などはコピーしたものを返すような設計が必要
→継承とコンポジション
→→継承は既知
→→→継承のメリット:利用が簡単
→→→継承のデメリット:サブクラスが良いカプセル化ではない、ひとクラスしか継承できない
→→コンポジション:元のクラスをバックエンドクラス、新しいクラスをフロントエンドクラス
→→→フロントエンドクラスはバックエンドクラスのインスタンスを利用する。
→→コンポジションのメリット:カプセル化が強い
→→コンポジションのデメリット:コーディングが増えて面倒
→→継承か、コンポジションかの判断の仕方
→→→A is BならAはBの継承とする
→→→A has B なら、AはBのコンポジションとする

[AS]getter/setterの明示型と暗黙型について

getter/setterの存在意義としては、オブジェクト指向における
「パブリックなプロパティを使わない」
という概念からあるっぽい。

ということは、プライベートなプロパティへのアクセス方法としてgetter/setter(アクセサメソッド)という概念があるということかな。

明示型のアクセサメソッドについて
パブリックな関数を用意してその戻り値にプライベートなプロパティを設定する。
こんな感じ。

package  {
	public class NewClass {
		
		private _number:Number = 10;
		
		public function getNumber():Number{
			return _number;
		}
		public function setNumber(num:Number):void{
			_number = num;
		}		
	}
}

こんな感じで呼び出す。

//フレームアクションとかで
var newClass:NewClass = new NewClass();
newClass.setNumber(200);
trace(newClass.getNumber) //出力:200

で、暗黙型のアクセサメソッドについて
いわゆる、よく参考書に書かれているアクセサメソッドを使った方法。
こんな感じ

package  {
	public class NewClass {
		
		private var _number:Number = 10;
		
		public function get number():Number {
			return _number; 
		}
		
		public function set number(value:Number):void 
		{
			_number = value;
		}
	}
}

こんな感じで呼び出す

//フレームアクションとかで
var newClass:NewClass = new NewClass();
newClass.number = 200;
trace(newClass.number) //出力:200

二つの違いは、通常通り関数としてアクセスするか、横着してプロパティっぽく使いたいかってことなのかな。

使い勝手として、元来、関数的な処理なので、例外処理とかを追加して使うのが王道っぽい。
たとえば、_numberには正の数値のみという条件があった場合は、
明示的な例

package  {
	public class NewClass {
		
		private var _number:Number = 10;
		
		public function getNumber():Number{
			return _number;
		}
		public function setNumber(num:Number):void{
			if (num < 0) {
				_number = 0;
			} else{
				_number = num;
			}
		}		
	}
}

getter/setterがプロパティもどきと、考えてたから色々こんがらがってた。
けれど元来は関数でやってたことをプロパティっぽく使える便利機能だよって感じだということを知って、ちょっと納得。

[AS]バネの動きの考え方について

とりあえずよくわすれるからメモ
バネの動きについて

原則としては、
単位時間での、「目的位置」 – 「現在位置」を「加速度」と設定する。
この加速度でオブジェクトを動かせばそれはバネの動きとなる。

ステージにball_mcをおいた状態でのフレームアクション
簡単に書くと、

//初速度
var v0x:Number=0;
//速度
var vx:Number=0;

addEventListener(Event.ENTER_FRAME, entarFrameHandler);
vx=v0x;
function entarFrameHandler(e:Event):void {
	//マウス位置とボールの位置の差を加速度とということにする
	//つまりは目的位置 - 現在位置 を加速度にするということ。
	//この加速度は毎フレームごとで当然変化する。
	//良くわからんが、(目的位置 - 現在位置) で求めた加速度はバネの性質を持つ
	var ax = mouseX - ball_mc.x;
	
	//速度に加速度を単位時間毎に足すということ
	vx += ax;
	
	//位置に速度を単位時間毎に足すということ
	//ここでの速度はマウス位置で変化
	ball_mc.x+=vx;
}

ただしこれだと、バネは収束しないので二つのパラメータを設定して制御。
空気抵抗:1以下の数値を設定し、バネの収束する速度を調整
バネ定数:1以下の数値を設定し、バネの硬さを調整(小さい方が軟らかくなる)

//初速度
var v0x:Number=0;
//速度
var vx:Number=0;
//バネ定数(1以下、数値を上げるほど硬いバネ)
var spring:Number = 1;
//空気抵抗(数値を下げるほど、行ったり来たりが短く)
var friction:Number = 0.9

addEventListener(Event.ENTER_FRAME, entarFrameHandler);
vx=v0x;
function entarFrameHandler(e:Event):void {
	//マウス位置とボールの位置の差を加速度とということにする
	//つまりは目的位置 - 現在位置 を加速度にするということ。
	//この加速度は毎フレームごとで当然変化する。
	var ax = mouseX - ball_mc.x;
	//加速度にバネ定数をかける
	//良くわからんが、(目的位置 - 現在位置) * バネ定数で求めた加速度はバネの性質を持つ
	//(目的位置 - 現在位置) (* バネ定数:かけなくてもバネっぽい動き)で求めた加速度、これを忘れないように。
	ax = ax * spring
	
	//速度に加速度を単位時間毎に足すということ
	vx += ax;
	//速度に空気抵抗かける
	vx *= friction;
	
	//位置に速度を単位時間毎に足すということ
	//ここでの速度はマウス位置で変化
	ball_mc.x+=vx;
}

[AS]速度と加速度の考え方について

よくこんがらがるので基本的なまとめ

基本概念
速度とは、単位時間あたりの位置の変化
加速度とは、単位時間あたりの速度の変化
(ここではENTER_FRAMEでの繰り返しを単位時間と設定する)

ステージにball_mcを配置した状態でのフレームアクション

等速運動

//初速度
var v0x:Number=10;
addEventListener(Event.ENTER_FRAME, entarFrameHandler);
function entarFrameHandler(e:Event):void {
	//位置に速度を単位時間毎に足すということ
	ball_mc.x+=v0x;
}

等加速度運動

//初速度
var v0x:Number=10;
//速度
var vx:Number=0;
//初加速度(そんな言い方あるのか)
var a0x:Number=1;

addEventListener(Event.ENTER_FRAME, entarFrameHandler);
//速度に初速度を代入
vx=v0x;
function entarFrameHandler(e:Event):void {
	//速度に加速度を単位時間毎に足すということ
	vx+=a0x;
	//位置に速度を単位時間毎に足すということ
	//ここでの速度はどんどん増えていく
	ball_mc.x+=vx;
}