본문 바로가기

개발/Etc

[Design Pattern] Observer Pattern

Observer Pattern 은 Behavioral Pattern(행동 패턴)에 속한다.


Observer Pattern

객체 사이에 1: N 의 종속성을 정의하고 한 객체의 상태가 변하면 종속된 다른 객체에 통보가 가고 자동으로 수정이 일어나게 하는 패턴이다.

Observer Pattern UML

  • Subject(Observable) : 관찰되는 대상을 관리한다.
  • ConcreteSubject : 구체 Subject를 표현하고, 상태 변경을 알려준다.
  • Observer : 상태 변경을 전달 받는다.
  • ConcreteObserver : 구체 Observer를 표현하고, 상태 변경 알림을 받는다.

언제 쓰면 좋을까?

한 객체의 상태가 다른 객체의 변화를 요구하는 경우에 사용한다. 즉 A 유투버가 새로운 영상을 올렸을 때, A를 구독하는 구독자들에게 알람을 줘야하는 상황과 비슷한 맥락에서 사용하면 좋다. 

예시 코드

천재 개발자 Addison의 수업을 듣는 Caden / Emma / Mia 학생이 있다.

Addison은 몸살이 자주나서 수업을 못할때가 많다. 그래서 Addison을 구독하는 학생들에게 수업 한시간전에 수업 가능 여부를 알려주려고 한다. 아래 코드를 확인해보자!

 

Observer

public interface Observer {
    void update(String msg);
}

ConcreteObserver

public class Caden implements Observer {
    @Override
    public void update(String msg) {
        System.out.println("Caden님 " + msg);
    }
}

public class Emma implements Observer {
    @Override
    public void update(String msg) {
        System.out.println("Emma님 " + msg);
    }
}

public class Mia implements Observer {
    @Override
    public void update(String msg) {
        System.out.println("Mia님 " + msg);
    }
}

Subject

public interface Observable {
    void subscribe(Observer observer);
    void unsubscribe(Observer observer);
    void notifyStudent(String msg);
}

ConcreteObserver

import java.util.ArrayList;
import java.util.List;

public class Addison implements Observable {

    private List<Observer> observers = new ArrayList<>();

    public void cancelLectures() {
        notifyStudent("몸살이 나서 수업 취소합니다.");
    }

    public void giveLectures() {
        notifyStudent("수업 합니다.");
    }

    @Override
    public void subscribe(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void unsubscribe(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyStudent(String msg) {
        observers.forEach(observer -> observer.update(msg));
    }
}

Client

public class Main {
    public static void main(String[] args) {
        Addison addison = new Addison();
        Observer caden = new Caden();
        Observer emma = new Emma();
        Observer mia = new Mia();

        addison.subscribe(caden);
        addison.subscribe(emma);
        addison.subscribe(mia);
        
        addison.cancelLectures();

        addison.unsubscribe(emma);
        addison.giveLectures();
    }
}

//결과
Caden님 몸살이 나서 수업 취소합니다.
Emma님 몸살이 나서 수업 취소합니다.
Mia님 몸살이 나서 수업 취소합니다.
Caden님 수업 합니다.
Mia님 수업 합니다.

장점 

  • 실시간으로 한 객체의 변경사항을 다른 객체에 알려줄 수 있다.
  • 느슨한 결합으로 객체간 의존성을 줄일 수 있다.

단점

  • 너무 많이 사용하게 될 경우 상태 관리가 힘들 수 있다.
  • Subject 에서 Observer 리스트를 순회하며 알림을 주긴하지만 Observer의 추가 및 삭제가 자유롭게 이루어지기 떄문에 개별 Observer 입장에서는 자신의 호출 순서를 알 수 없게 된다. 

관련 패턴

  • Mediator Pattern : M : N의 관계에서 M : 1의 관계로 표현하는 패턴이다.

'개발 > Etc' 카테고리의 다른 글

UUID type3, UUID type4 (JAVA)  (0) 2021.08.24
[Design Pattern] Bridge Pattern  (0) 2021.08.11
[Design Pattern] Prototype Pattern  (0) 2021.08.07
[Design Pattern] 디자인 패턴 23 가지  (0) 2021.08.04