Facade

Facadeパターンは、本来クライアントが操作しなければならないシステムが複雑(あるいは煩雑)な場合に、その複雑な部位をクライアントから隠してしまい代わりに扱いの易しい(あるいは明瞭な)インターフェイス(注意:ActionScrptのinterfaceではない)を提供する手法である。パターンと呼ぶと仰々しいが考え方は実にシンプルで、ゴチャゴチャしたソースコードを一つのメソッドにまとめてしまうというのも一種のFacadeパターンと考えると、ほとんどのプログラマーが一度は実装したことのある馴染みの深いものではないだろうか。

Example

以下はあまり良い例ではないと思われる。というのは現実的な"煩雑なシステム"の良い例を思いつかなかったからである。 その点を考慮して読み進めてもらえるとありがたい。Facadeパターンの説明としてはこれで十分事足りていると思う。 ("Erich Gamma - Design Patterns"ではプログラムのコンパイル操作を複雑なシステムの例として挙げている)

次のようなシステム(subsystem)があったとしよう。

つまりこのシステム本体を起動させるためには以下の順序に従った操作が必要なことがわかる。
  1. ボタン1を押す。
  2. ボタン2を押す。
  3. ボタン3を押す。
  4. システム本体を起動する。
このような煩雑なシステムをクライアントが直接操作することが危険なことはすぐわかるであろう。 操作の手順を間違えるとたちまち機能しなくなってしまうからだ。 そこでFacadeパターンを導入し、クライアントがシステムを簡単に起動できるような新しいインターフェイスを提供することを試みる。 以下の例では、上記システムをクラスに見立てている。それぞれの関係は以下の通りである。 注目してもらいたいのはクライアントではシステムを直接操作せず、 かわりにFacadeクラスに煩雑な操作全てをまかせている点である。 こうすることでクライアントは簡単な操作でシステムを起動させることができるのである。

//main.as
package {
	import flash.display.Sprite;
 
	public class main extends Sprite{
		public function main(){
			var facade:Facade = new Facade();
			facade.execute();
		}
	}
}
//Facade.as
package{
	import subsystem.FirstButton;
	import subsystem.SecondButton;
	import subsystem.ThirdButton;
	import subsystem.Executor;
 
	public class Facade{
		public function Facade(){
		}
 
		public function execute():void{
			var btn1:FirstButton = new FirstButton();
			var btn2:SecondButton = new SecondButton(btn1);
			var btn3:ThirdButton = new ThirdButton(btn2);
			var executor:Executor = new Executor(btn1, btn2, btn3);
			btn1.press();
			btn2.press();
			btn3.press();
			executor.execute();
		}
	}
}
//AButton.as (Abstract)
package subsystem{
	public class AButton{
 
		protected var _isPressed:Boolean;
		public function get isPressed():Boolean{
			return _isPressed;
		}
		public function set isPressed(value:Boolean):void{
			_isPressed = value;
		}
 
		public function AButton(){
			_isPressed = false;
		}
 
		public function press():void{
			_isPressed = true;		
		}
	}
}
//FirstButton.as
package subsystem{
	public class FirstButton extends AButton{
		public function FirstButton(){
		}
 
		override public function press():void{
			_isPressed = true;
		}
	}
}
//SecondButton.as
package subsystem{
	public class SecondButton extends AButton{
		protected var _firstButton:FirstButton;
 
		public function SecondButton(firstButton:FirstButton){
			_firstButton = firstButton;
		}
 
		override public function press():void{
			if (_firstButton.isPressed){
				_isPressed = true;
			}
		}
	}
}
//ThirdButton.as
package subsystem{
	public class ThirdButton extends AButton{
		protected var _secondButton:SecondButton;
 
		public function ThirdButton(secondButton:SecondButton){
			_secondButton = secondButton;
		}
 
		override public function press():void{
			if (_secondButton.isPressed){
				_isPressed = true;
			}
		}
	}
}
//Executor.as
package subsystem{
	public class Executor{
		protected var _btn1:FirstButton;
		protected var _btn2:SecondButton;
		protected var _btn3:ThirdButton;
 
		public function Executor(btn1:FirstButton,btn2:SecondButton,btn3:ThirdButton){
			_btn1 = btn1;
			_btn2 = btn2;
			_btn3 = btn3;
		}
 
		public function execute():void{
			if (_btn1.isPressed && _btn2.isPressed && _btn3.isPressed){
				trace("The execution succeeded.");
			}
			else{
				trace("The execution failed.");
				_btn1.isPressed = false;
				_btn2.isPressed = false;
				_btn3.isPressed = false;
			}
		}
	}
}
© 2009 7614.org