본문 바로가기

프로그래밍/패턴,설계,자료구조

옵저버 패턴 ( Observer Pattern ) [ Head First Design Pattern 내용중에서 ]


옵저버 패턴 : 한객체의 상태가 바뀌면 그 객체 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many)의존성을 정의 한다.


디자인 원칙 : 서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다.

<예제 : 기상 스테이션( Action Script 3.0 ) >

====== 인터페이스 선언 =========
//주제 인터페이스 
	public interface Subject
	{
		 function registerObserver( o : Observer ):void;
		 function removeObserver( o : Observer ):void;
		 function notifyObserver( ):void;		
		 function setChanged() :void;
		
	}
//옵저버 인터페이스 
public interface Observer
	{
		 function update( tmep : int , humidity : int , pressure : int ):void; 
	}
//Display 관련 인터페이스 
	public interface DisplayElement
	{
		 function display():void;
	}
====== 인터페이스 구현 =========
//Subject interface 구현
	public class WeatherData implements Subject
	{
		private var arObserver : Array;
		private var temperature : int ;
		private var humidity : int ;
		private var pressure : int ;
		
		private var changed : Boolean = false;
		
		public function WeatherData()
		{
			arObserver = [];
		}
		
		public function registerObserver(o:Observer):void
		{
			this.arObserver.push( o );
		}
		
		public function removeObserver(o:Observer):void
		{
				
			var lastIndex : Number = 	this.arObserver.length;
			
			for( var i : Number =0; i< lastIndex; i++){
				if( this.arObserver[i]== o ){
					this.arObserver.splice( i, 1 );
				}						
			}
			
		}
		
		public function notifyObserver():void
		{
			
			for( var i : Number= 0 ; i< this.arObserver.length; i++ ){				
				Observer(arObserver[i]).update(  	this.temperature, 	this.humidity, 		this.pressure );
			}
			
		}
		
		public function measureChanged( ) :void
		{
			setChanged();
			notifyObserver();
			
		}
		
		
		public function setMeasurements( temperature : int,  humidity : int, pressure : int ) :void
		{
		
			this.temperature = temperature;
			this.humidity = humidity;
			this.pressure = pressure;
			
			measureChanged();			
		}
		
		public function setChanged():void
		{
			this.changed = true;			
		}
		

		
	}
//Observer, DisplayElement 인터 페이스 구현 
package weather
{
	public class CurrentConditionsDisplay implements Observer, DisplayElement
	{
		
		private var _temp : int;
		private var _humidity : int;
		private var _weatherData : Subject;
		
		public function CurrentConditionsDisplay( weatherData : Subject )
		{
			this._weatherData = weatherData;
			_weatherData.registerObserver( this );
		}
		
		public function update(temp:int, humidity:int, pressure:int):void
		{ 
			
			this._temp = temp;
			this._humidity = humidity;
			display();			
					
		}
		
		public function display():void
		{
			trace( "Current conditions:"+ this._temp +"F degress and "+ this._humidity + " humidity" );
		}
	}
}
<실행>
	public class ObserverPatternTest extends Sprite
	{
		public function ObserverPatternTest()
		{
			super();
			
			var weatherData :WeatherData = new WeatherData();			
			var conditionDisplay : CurrentConditionsDisplay = new CurrentConditionsDisplay( weatherData );			
                                                   //interface에 맞춰진 옵저버는 얼마든지 등록할수 있다.
			weatherData.setMeasurements( 80, 65, 30 );		 
			
		}
	}