ObserverパターンをActionScriptで書く
『Head First デザインパターン 頭とからだで覚えるデザインパターンの基本』p57〜p60より
ObserverパターンをActionScriptで書くと・・・
Subjectインターフェース
// ISubject
package
{
public interface ISubject
{
function addObserver(o:IObserver):void;
function removeObserver(o:IObserver):void;
function notifyObservers():void;
}
}
Observerインターフェース
// IObserver
package
{
public interface IObserver
{
// floatをNumberに
function update(temp:Number, humidity:Number, pressure:Number):void;
}
}
DisplayElementインターフェース
// IDisplayElement
package
{
public interface IDisplayElement
{
function display():void;
}
}
WeatherDataクラス
// WeatherData
package
{
public class WeatherData implements ISubject
{
private var _observers:Array;
private var _temperature:Number;
private var _humidity:Number;
private var _pressure:Number;
public function WeatherData()
{
init();
}
private function init():void
{
_observers = [];
}
public function addObserver(o:IObserver):void
{
// addをpushに
_observers.push(o);
}
public function removeObserver(o:IObserver):void
{
// removeをspliceで代用
var i:int = _observers.indexOf(o);
if (i >= 0) _observers.splice(i, 1);
}
public function notifyObservers():void
{
var i:int;
// 高速化のため、あえてlengthをローカル変数に入れる
var length:int = _observers.length;
for (i = 0; i < length; i++)
{
// getを[i]に
var observer:IObserver = IObserver(_observers[i]);
observer.update(_temperature, _humidity, _pressure);
}
}
public function measurementsChanged():void
{
notifyObservers();
}
public function setMeasurements(temperature:Number, humidity:Number, pressure:Number):void
{
_temperature = temperature;
_humidity = humidity;
_pressure = pressure;
measurementsChanged();
}
}
}
CurrentConditionsDisplayクラス
// CurrentConditionsDisplay
package
{
public class CurrentConditionsDisplay implements IObserver, IDisplayElement
{
private var _temperature:Number;
private var _humidity:Number;
private var _pressure:Number;
private var _weatherData:WeatherData;
public function CurrentConditionsDisplay(weatherData:ISubject)
{
// WeatherDataでキャストする
_weatherData = WeatherData(weatherData);
init();
}
private function init():void
{
_weatherData.addObserver(this);
}
public function update(temperature:Number, humidity:Number, pressure:Number):void
{
_temperature = temperature;
_humidity = humidity;
_pressure = pressure;
display();
}
public function display():void
{
trace("現在の気象状況:温度" + _temperature + "度 湿度" + _humidity + "% 気圧" + _pressure);
}
}
}
Mainクラス
// Main
package
{
import flash.display.Sprite;
import flash.events.Event;
public class Main extends Sprite
{
private var _weatherData:WeatherData;
private var _currentDisplayCondition:CurrentConditionsDisplay;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(event:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
_weatherData = new WeatherData();
_currentDisplayCondition = new CurrentConditionsDisplay(_weatherData);
test();
}
private function test():void
{
_weatherData.setMeasurements(27, 65, 30.4);
_weatherData.setMeasurements(28, 70, 29.2);
_weatherData.setMeasurements(26, 90, 29.2);
}
}
}
