본문 바로가기
Programming/DesignPattern

[디자인 패턴] 옵저버(Observer) 패턴

by Blemish 2021. 4. 30.

 

옵저버 패턴 (Observer Pattern)

  • 한 객체의 상태가 변경되면 그 객체를 의존하는 다른 객체들에게 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다(One - to - Many) 의존성을 정의
  • 분산 이벤트 핸들링 시스템을 구현할 때 사용

 

 

클래스 다이어그램

 

  • Observer : 데이터의 변경을 통보받는 인터페이스
  • Subject : ConcreteObserver 객체를 관리하는 요소
  • ConcreteSubject : 변경 관리 대상이 되는 데이터가 있는 클래스. Subject의 Notify를 호출함으로써 ConcreteObserver 객체에 변경을 통보
  • ConcreteObserver : ConcreteSubject의 변경을 통보받는 클래스. Observer 인터페이스의 Update() 메서드를 구현함으로써 변경을 통보받는다.

 

 

예제(Example)

  • 성적을 입력하면 입력된 성적 값을 출력하는 프로그램을 구현

   

클래스 다이어그램

  • ScoreRecord : 점수를 입력하는 클래스
  • DataSheetView : 입력된 점수를 목록의 형태로 출력하는 클래스

 

 

Question

  • 성적을 다른 형태로 출력하고 싶다면 어떤 변경 작업을 해야 하는가? 예를 들어 성적을 목록으로 출력하지 않고 성정의 최소/최대 값만 출력하려면?
    • 해결방법 : 최소값과 최대값을 출력할 수 있는 클래스를 생성(MinMaxView)한 다음 ScoreRecord 클래스에 SetMinMaxView()를 추가한 다음 AddScore()에서 MinMaxView.Update()를 호출하는 방식으로 변경해야함
  • 여러 가지 형태의 성적을 동시 혹은 순차적으로 촐력하려면 어떤 변경 작업을 해야 하는가? 예를 들어 성적이 입력되었을 때 최대 3개 목록, 최대 5개 목록, 최소/최대 값을 동시에 출력하거나 처음에는 목록으로 출력하고 나중에는 최소/최대 값을 출력하려면?
    • 해결방법 : 최소값과 최대값을 출력할 수 있는 클래스를 생성(MinMaxView)한 다음 ScoreRecord 클래스에 SetMinMaxView()를 추가한 다음 AddScore()에서 MinMaxView.Update()를 추가로 호출하는 방식으로 변경하고 Client(Main)에서 ViewCount 값을 변경

 

위의 해결방법의 문제점은 기존의 코드를 수정하기 때문에 OCP에 위배된다.

 

 

해결방법

  • ScoreRecord 클래스에서 변화되어야 하는 부분을 식별한 다음 일반화 한다.
  • 객체의 Update 메서드를 호출하는 기능은 성적 변경뿐만 아니라 임의의 데이터가 변경되었을 때 변경되어야하는 객체에 통보해야한다. 이러한 공통기능을 위해 상위 클래스 및 인터페이스로 일반화하고 이를 활용해서 ScoreRecord를 구현해야한다.
  • 성적 변경에 관심이 있는 객체를 관리하는 기능을 구현하는 Subject 클래스 구현한 후 NotifyObserver() 메서드를 사용하여 DataSheetView, MinMaxView 클래스에 성적을 통보
  • Observer 인터페이스를 구현

클래스 다이어그램

 

 

댓글