Korea Polytechnic University Advanced Game Software Engineering Student Presentation Advanced Game Software Engineering Student Presentation Chapter 2 Observer Pattern 학번 : 이름 : 변현준 학번 : 이름 : 변현준
Advanced Game Software Engineering Student Presentation Presentation Outline Observer Pattern 의 정의 기상 모니터링 Application Observer Pattern 기상 스테이션 자바 내장 옵저버 패턴 정리
Advanced Game Software Engineering Student Presentation 옵저버 패턴의 정의 옵저버 패턴 ( Observer Pattern ) 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 개체들한테 연락이 가고 자동으로 내 용이 갱신되는 방식으로 일대다 (one-to-many) 의존성을 정의한다.
Advanced Game Software Engineering Student Presentation 기상 모니터링 Application Weater-O-Roma 에서 제공하는 정보를 통해 애플리케이션을 만들어라 !!! 이 시스템은 기상 스테이션과 WaetherData 객체, 그리고 디스플레이, 이렇게 세 요소로 이루어져 있음. 기상스테이션 : 실제기상 정보를 수집하는 장비 WeatherDate 객체 : 기상 스테이션으로부터 오는 데이터를 추적하는 객체 디스플레이 : 사용자에게 현재 기상 조건을 보여주는 디스플레이 WeatherData 객체에서는기상 스테이션 장비로부터 데이터를 가져올 수 있음. 데이터를 가져온 후에는 디스플레이 장비에서 세가지 항목 표시 가능. 현재조건 ( 온도, 습도, 압력 ) 기상 통계 기상 예보 기상 스테이션 WeatherData 객체 현재조건 온도 : 72 도 F 습도 : 60 압력 : ↓ 디스플레이 장비
Advanced Game Software Engineering Student Presentation 기상 모니터링 Application 습도센서 온도센서 압력센서 기상 스테이션 WeatherData 객체 현재조건 온도 : 72 도 F 습도 : 60 압력 : ↓ 디스플레이 장비 화면에 표시 데이터 취득 Weather-O-Roma 와 계약을 체결하게 되면 WeatherData 객체를 사용하여 현재 조 건, 기상 통계, 기상 예측, 이렇게 세 항목을 디스플레이 장비에서 갱신해 가면서 보여주는 애플리케이션을 만들어야 한다. 시스템이 확장 가능해야 한다. 다른 개발자들이 별도의 디스플레이 항목을 만들 수 있고 사용자들이 디스플레이 항목을 추가 / 제거 가능해야 한다. Weather-O-Roma 에서 제공하는 부분 구현해야 할 부분
Advanced Game Software Engineering Student Presentation 기상 모니터링 Application WeatherData 소스 기상 스테이션용 코드 public void measurementsChanged() { float temp = getTemperature(); float humidity = getHumidity(); float pressure = getPressure(); currentConditionDisplay.update(temp, humidity, pressure); statisticsDisplay.update(temp, humidity, pressure); forecastDisplay.update(temp, humidity, pressure); } 구체적인 구현 메소드를 사용하여 디스플레이 항목 추가 / 제거시 수정사항 많음. 세가지 형태의 디스플레이 되는 부분은 추가 / 삭제될 수 있으니 이 부분을 캡슐화해 야 한다. WeatherData getTemperature() getHumidity() getPressure() measurementsChanged() // 기타 메소드 measurementsChanged() 기상 관측값이 갱신될 때마다 알려주기 위한 메소드
Advanced Game Software Engineering Student Presentation 옵저버 패턴 출판사 + 구독자 = 옵저버 패턴 신문 구독 메커니즘을 알면 옵저버 패턴을 이해할 수 있다. 신문사는 신문이 바뀔 때마다 정기구독자에게 알린다. 정기구독자는 본인의 의사에 의해 신문 구독을 해지 / 신청이 가능하다. 신판사 = 주제 (subject) 구독자 = 옵저버 (Observer) 주제가 변경되면 옵저버에게 주제가 전달되고 옵저버는 추가되거나 제거될 수도 있다. 이때 옵저버는 주제에게 등록요청을 하고 해지요청을 한다. 하나의 신문사가 여러 명의 구독자에게 정보를 전달하는 것은 일대다의 관계이다. 이는 옵저버의 상태를 관장하는 객체는 하나이고, 옵저버는 여러 개란 말.
Advanced Game Software Engineering Student Presentation 옵저버 패턴 Duck 객체가 주제 객체에게 옵저버가 되고 싶다고 함. Duck 객체는 공식적인 옵저버가 됨. 주제 객체의 값이 바뀌면 Duck 을 포함한 모든 옵저버들이 연락을 받게 됨. Mouse 객체가 옵저버 목록에서 탈퇴 요청. Mouse 는 빠지게 됨. 주제 객체에 새로운 int 값이 들어오면 Mouse 한테는 연락이 가지 않음. 옵저버 객체 Int 2 Dog 객체 Cat 객체 Mouse 객체 Duck 객체 주제 객체 옵저버가 아니라 연락 못 받음 주제의 데이터가 바뀌면 갱신내용 전달받음. 주제의 데이터가 달라지면 옵저버한테 소식 전달 주제 객체에서 일부 데이터 관리
Advanced Game Software Engineering Student Presentation 옵저버 패턴 옵저버 패턴은 신문사와 정기구독자로 이루어지는 신문 구독 서비스에 비유. 옵저버 패턴은 다음과 같은 식으로 정의 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 개체들한테 연락이 가고 자동으로 내 용이 갱신되는 방식으로 일대다 (one-to-many) 의존성을 정의한다. 일대다 관계는 주제와 옵저버에 의해 정의 옵저버는 주제에 의존. 주제의 상태가 바뀌면 옵저버한테 연락. 연락 방법에 따라 옵저버에 있는 값이 새로운 값으로 갱신. 옵저버 패턴을 구현하는 방법은 여러 가지며, 대부분 주제인터페이스와 옵저버인 터페이스가 들어있는 클래스 디자인을 바탕으로 함. > Subject registerObserver() removeObserver() notifyObserver() > Observer Update() ConcreteSubject registerObserver() {…} removeObserver() {…} notifyObserver() {…} getState() setState() ConcreteObserver Update() // 기타 옵저버용 메소드 주제 옵저버
Advanced Game Software Engineering Student Presentation 옵저버 패턴 느슨한 결합 두 객체가 느슨하게 결합되어 있다는 것은, 그 둘이 상호작용을 하긴 하지만 서로에 대해 서로 잘 모른다는 것을 의미. 옵저버 패턴에서는 주제와 옵저버가 느슨하게 결합되어 있는 객체 디자인을 제공 느슨한 결합 (Loose Coupling) : subject 와 observer 가 느슨하게 묶임 ( 서로가 서로를 모 름 ) subject 가 observer 에 대해 아는 것은 observer 가 특정 인터페이스를 구현한다는 것 뿐 : update() observer 는 언제든 새로 추가 가능. 제거 또한 마찬가지. 새 observer 를 추가해도 subject 를 변경할 필요 없음 subject 와 observer 는 독립적으로 재사용 가능 subject 또는 observer 가 변경되어도 서로 영향 안 미침 서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사 용하라. 변경사항이 생겨도, 객체 사이의 상호 의존성을 최소화하여 변경 가능한 유연성 확보 가 능
Advanced Game Software Engineering Student Presentation 기상 스테이션 – 기상 스테이션 설계 다이어그램 > Subject registerObserver() removeObserver() notifyObserver() WeatherData registerObserver() removeObserver() notifyObserver() getTemperature() getHumidity() getPressure() measurementsChanged() > Observer Update() > DisplayElement Display() CurrentConditionsDisplay Update() Display() { 현재 측정값 표시 } StatisticsDisplay Update() Display() { 평균 / 최저 / 최고치 표시 } ForecastDisplay Update() Display() { 기상 예보 표시 } ThirdPartyDisplay Update() Display() { 측정값을 바탕으로 다른 내용 표시 } 옵저버 주제
Advanced Game Software Engineering Student Presentation 기상 스테이션 주제를 나타내는 Subject 인터페이스는 객체에서 옵저버로 등록하거나 옵저버 목록에서 탈 퇴하고 싶을 때 이 인터페이스의 메소드를 사용. 주제 역할을 하는 구상 클래스에서는 항상 Subject 인터페이스를 구현해야 한다. 주제 클래 스에서는 등록 및 해지를 위한 메소드 외에 상태가 바뀔 때마다 모든 옵저버들에게 연락을 하기 위한 notifyObservers() 메소드를 구현해야 한다. 주제 클래스에는 상태를 설정하고 알아내기 위한 setter/getter 메소드가 들어 있을 수 있다. 각 주제마다 여러 개의 옵저버가 있을 수 있다. 옵저버가 될 가능성이 있는 객체에서는 반드시 Observer 인터페이스를 구현해야 한다. 이 인 터페이스에는 주제의 상태가 바뀌었을 때 호출되는 update() 메소드만을 포함하고 있다. Observer 인터페이스만 구현한다면 무엇이든 옵저버 클래스가 될 수 있다. 각 옵저버는 특정 주제에 객체에 등록을 해서 연락을 받을 수 있다. Observer 의 구상 클래스 (CurrentConditionsDisplay, StatisticsDisplay, ForecastDisplay..) 에 서 registerObserver() 를 이용해 Subject 에 등록. removeObserver() 를 통해 Subject 에서 해제. Subject 에서 상태가 바뀜. notifyObservers() 를 호출. 모든 Observer 클래스에서 update() 를 수행. Update() 함수 호출 시에 매개변수로 값을 넘김. Subject 에 setter/getter 함수를 두어 Observer 에서 참조 가능.
Advanced Game Software Engineering Student Presentation 자바 내장 옵저버 패턴 – 정보 취득 방식 주제는 계속 데이터를 보내는데 옵저버는 필요할 때만 데이터를 받고 싶다. 푸시 (push) 방식 주제가 데이터를 보내는 방식 풀 (pull) 방식 옵저버가 데이터를 가져가는 방식 자바에 내장된 옵저버 패턴을 통해 마음대로 사용가능 Observable 클래스 사용. java.util.Observer, java.util.Observable 에 있는 API 사용 addObserver, deleteObserver, notifyObservers 같은메소드를 상속 받음.
Advanced Game Software Engineering Student Presentation 자바 내장 옵저버 패턴 객체가 옵저버가 되는 방법 Observer 인터페이스를 구현 Observable 객체의 addObserver() 메소드를 호출 옵저버 목록에서 탈퇴하고 싶을 때는 deleteObserver() 호출 Observable 에서 연락을 돌리는 방법 Java.util.Observable 수퍼클래스를 확장하여 Observable 클래스를 만들어야 한다. 첫 번째로 할 일은 setChanged() 메소드를 호출해서 객체의 상태가 바뀌었다는 것을 알 림. notifyObservers() 또는 notifyObservers(Object arg) 메소드 호출 옵저버가 연락을 받는 방법 Update(Observable o, Objecgt arg)
Advanced Game Software Engineering Student Presentation 자바 내장 옵저버 패턴 setChanged() { changed = true; } notifyObservers(Object arg) { if(changed) { for( 목록에 있는 모든 옵저버에 대해 ) { update(this, arg); } changed = false; } setChanged() : Observable 클래스에 포함되어있는 메소드 setChanged() 메소드는 changed 플래그의 값을 참으로 설정하고, notifyObservers() 에서는 changed 플래그가 참인 경우만 옵저버에게 연락.
Advanced Game Software Engineering Student Presentation 자바 내장 옵저버 패턴 java.util.Observable 의 단점 Observable 은 클래스이기 때문에 서브클래스를 만들어야한다. 때문에 다른 수퍼클래스를 확장하고 있는 클래스에 Observable 기능 추가 못 함. 재사용성에 제약 Observable 인터페이스라는 것이 없어 Observer API 와 맞는 클래스 직접 구현 불가능. java.util 구현을 다른 구현으로 바꾸는 것도 불가능. 멀티스레드 구현 X Observable 클래스의 핵심 메소드를 외부에서 호출 불가. setChanged() 메소드가 protected 로 선언되어 Observable 서브클래스에서만 호출 가능. java.util.Observable 을 확장한 클래스를 쓸 수 있는 상황일 때 사용. 직접구현.
Advanced Game Software Engineering Student Presentation 정리 객체지향 원칙 바뀌는 부분은 캡슐화 상속보다는 구성을 활용 구현이 아닌 인터페이스에 맞춰서 프로그래밍 서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인 사용 옵저버 패턴 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내 용이 갱신되는 방식으로 일대다 (one-to-many) 의존성을 정의