Study/CS

[CS] 디자인패턴 - 옵저버 패턴

dev_kong 2023. 1. 5. 23:12
728x90
728x90

 

디자인 패턴이란?
프로그램을 설계할 때 발생했던 문제점들을 해결 할 수 있도록 하나의 규약형태로 만들어 놓은 것.

 

옵저버 패턴

 

옵저버 패턴이란?
주체가 어떤 객체의 상태 변화를 관찰하다가, 상태 변화가 있을 때마다 메서드 등을 통해 옵저버 목록에 잇는 옵저버들에게
변화를 알려주는 디자인 패턴이다.

 

위에서 말하는 주체란 객체의 상태 변화를 관찰자이며,
옵저버들이란 이객체의 상태변화에 따라 전달되는 메서드 등을 기반으로
추가 변경사항이 생기는 객체들을 의미한다.

 

또한 주체와 객체를 따로 두지 않고, 상태가 변경되는 객체를 기반으로 구축하기도 한다.

 

옵저버 패턴은 MVC 패턴에도 사용 되기도 한다.
주체라고 할 수 있는 model에서 변경사항 생겨 이를 메서드를 통해 view에게 알려주고,
이를 기반으로 controller가 작동한다.

 

예제 코드

 

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

public 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() {
        observers.forEach(Observer::update);
    }

    @Override
    public Object getUpdate(Observer obj) {
        return message;
    }

    public void postMessage(String msg) {
        System.out.println("Message sended to Topic: " + msg);
        this.message = msg;
        notifyObservers();
    }
}

 

주체이자, 객체가 되는 topic이다.


postMessage method가 실행되면,
topic이 변경되고,
topic의 변경을 notifyObservers method를 통해 observer들에게 알려준다.

 

public interface Observer {
    public void update();
}

public class TopicSubscriber implements Observer{
    private final String name;
    private final 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 이다.


update method는 topic의 notifyObservers를 통해 호출 된다.

이렇게 해놓고 한번 실행해보자,

 

public static void observer() {
        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("배고파");
}

이렇게 실행을 하면,

 

Message sended to Topic: 배고파
a:: got message >> 배고파
b:: got message >> 배고파
c:: got message >> 배고파

 

위와 같이 출력되는 것을 확인할 수 있다.

 

의문

 

topic의 getUpdate method가 뭐하는 앤지 잘 모르겠다.

 

@Override
public Object getUpdate(Observer obj) {
    return message;
}

 

왜 리턴타입이 Object인지도 모르겠고,
Observer를 인자값으로 받아서 아무것도 안하는데 왜 받는 건지도 모르겠다....

 

궁금증이 해소되면 수정예정

728x90
728x90