옵저버(Observer) 패턴

Ryu·2023년 3월 31일
0

옵저버(observer) 패턴이란?

옵저버 패턴은 주체가 어떤 객체(subject)의 상태 변화를 관찰하다가 상태 변화가 있을 때마다 메서드 등을 통해 옵저버 목록에 있는 옵저버들에게 변화를 알려주는 디자인 패턴입니다.

여기서 말하는 주체란 객체의 상태 변화를 보고있는 관찰자이며, 옵저버들이란 '추가 변화 사항'이 생기는 객체들을 의미합니다.
이때, 주체와 옵저버의 관계는 1:1이 될 수도 있고 1:N이 될 수도 있습니다.

옵저버 패턴의 사용

옵저버 패턴을 활용한 서비스로는 트위터가 있습니다.
아래 그림처럼 내가 어떤 사람인 주체를 '팔로우'했다면 주체가 포스팅을 올렸을 때 알림이 '팔로워'에게 가야할 것입니다.

또한, 옵저버 패턴은 주로 이벤트 기반 시스템에 사용하며 MVC(Model-View-Controller) 패턴에도 사용됩니다.

주체라고 볼 수 있는 모델(model)에서 변경 사항이 생겨 update() 메서드로 옵저버인 뷰에 알려주고 이를 기반으로 컨트롤러 등이 작동하는 것입니다.

옵저버 패턴 예시

자바

인터페이스 : Subject, Observer

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

interface Subject {
    public void register(Observer obj);
    public void unregister(Observer obj);
    public void notifyObservers();
    public Object getUpdate(Observer obj);
}

interface Observer {
    public void update(); 
}

1st class : Topic (implements Subject)

//Subject interface 구현 
class Topic implements Subject {
    private List<Observer> observers;
    private String message; 

    public Topic() {
        this.observers = new ArrayList<>();
        this.message = "";
    }

    @Override
    public void register(Observer obj) {
        if (!observers.contains(obj)) observers.add(obj); 
    }

    @Override
    public void unregister(Observer obj) {
        observers.remove(obj); 
    }

    @Override
    public void notifyObservers() {   
        this.observers.forEach(Observer::update); 
    }

    @Override
    public Object getUpdate(Observer obj) {
        return this.message;
    } 
    
    public void postMessage(String msg) {
        System.out.println("Message sended to Topic: " + msg);
        this.message = msg; 
        notifyObservers();
    }
}

2nd class : TopicSubscriber (implements Observer)

class TopicSubscriber implements Observer {
    private String name;
    private Subject topic;

    public TopicSubscriber(String name, Subject topic) {
        this.name = name;
        this.topic = topic;
    }

    @Override
    public void update() {
        String msg = (String) topic.getUpdate(this); 
        System.out.println(name + ":: got message >> " + msg); 
    } 
}

하나의 topic에 대해 observer가 3개이고 topic.postMessage()를 통해 topic에게 생긴 변화를 메세지를 통해 옵저버 a,b,c가 모두 받고 있는 것을 확인할 수 있습니다.

public class HelloWorld { 
    public static void main(String[] args) {
        Topic topic = new Topic(); 
        //옵저버를 선언할 때 해당 이름과 어떤 토픽의 옵저버가 될 것인지 결정 
        Observer a = new TopicSubscriber("a", topic);
        Observer b = new TopicSubscriber("b", topic);
        Observer c = new TopicSubscriber("c", topic);
        //옵저버 추가
        topic.register(a);
        topic.register(b);
        topic.register(c); 
   
        topic.postMessage("amumu is op champion!!"); 
    }
}
/*
Message sended to Topic: amumu is op champion!!
a:: got message >> amumu is op champion!!
b:: got message >> amumu is op champion!!
c:: got message >> amumu is op champion!!
*/ 

옵저버 패턴의 장단점

장점

  1. 실시간으로 한 객체의 변경사항을 다른 객체에 전파할 수 있다.
  2. 느슨한 결합으로 시스템이 유연하고 객체간의 의존성을 제거할 수 있다.

단점

  1. 너무 많이 사용하게 되면 상태 관리가 힘들 수 있다.
  2. 데이터 배분에 문제가 생기면 자칫 큰 문제로 이어질 수 있다.
profile
나는야 머찐 개발자

0개의 댓글