관리 메뉴

나만을 위한 블로그

[Android] 관찰자(Observer) 패턴이란? 본문

개인 공부/디자인 패턴

[Android] 관찰자(Observer) 패턴이란?

참깨빵위에참깨빵_ 2021. 4. 11. 00:06
728x90
반응형

냅뒀던 MVVM 패턴 공부를 다시 하려고 예제를 찾아서 분석하던 도중 MutableLiveData를 발견했다.

이게 아니라도 LiveData라는 키워드를 써서 LiveData<List<DTO>> 형태로 사용하는 예제 코드가 정말 많았다.

이게 뭔지 알면 MVVM 패턴에 한 걸음 다가가는 데 도움이 될 것이라고 생각해서 찾아봤더니 LiveData는 관찰자 패턴이란 걸 사용한다고 한다. 그래서 관찰자 패턴에 대해 정리하고자 한다.

 


 

관찰자(Observer) 패턴이란 뭘까? 관찰자라는 건 뭔가를 항상 살펴보고 있는 사람이라는 단어다.

그럼 뭘 관찰하고 있는 건가? 의미없는 걸 지켜보고 있지는 않을 것이다. 위키백과에선 아래와 같이 말하고 있다.

관찰자 패턴은 객체의 상태 변화를 관찰하는 관찰자들, 즉 옵저버들의 목록을 객체에 등록해서 상태변화가 있을 때마다 메서드 등을 통해 객체가 직접 목록의 각 옵저버에게 알리도록 하는 디자인 패턴이다. 이 패턴의 핵심은 옵저버 또는 리스너라 불리는 하나 이상의 객체를 관찰 대상이 되는 객체에 등록시킨다. 그리고 각각의 옵저버들은 관찰 대상인 객체가 발생시키는 이벤트를 받아 처리한다. 이벤트가 발생하면 각 옵저버는 콜백을 받는다.

옵저버 패턴은 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들에게 연락이 가고 자동으로 정보가 갱신되는 1:N의 관계를 정의하고, 주제와 옵저버가 느슨하게 결합된 디자인 패턴이다.

또한 한 객체가 상태를 변경하면 모든 종속 객체가 자동으로 알림을 받고 업데이트된다. 그래서 이 패턴은 객체 상태의 변화를 알림으로 받고 싶을 때 생각해볼 수 있다.

주제가 옵저버에 대해 아는 건 옵저버가 특정 인터페이스를 구현한다는 것 뿐이고, 옵저버는 계속 추가될 수 있다.

 

이제 예제로 옵저버 패턴을 확인해보자.

먼저 Observer, Subject라는 이름의 인터페이스를 만든다.

public interface Observer
{
    void update(Message m);
}
public interface Subject
{
    void attach(Observer observer);
    void detach(Observer observer);
    void notifyUpdate(Message message);
}

그리고 Message 클래스를 만든다.

public class Message
{
    final String messageContent;

    public Message(String m)
    {
        this.messageContent = m;
    }

    public String getMessageContent()
    {
        return messageContent;
    }

}

그리고 MessagePublisher, NewsSubscriber 클래스를 만들고 각각 Subject, Observer 인터페이스를 구현해준다.

 

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

public class MessagePublisher implements Subject
{
    private final List<Observer> observers = new ArrayList<>();

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

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

    @Override
    public void notifyUpdate(Message message)
    {
        for (Observer o : observers)
        {
            o.update(message);
        }
    }
}
public class NewsSubscriber implements Observer
{
    private String observerName;
    private String news;
    private Publisher publisher;

    public NewsSubscriber(String subscriber, Publisher publisher)
    {
        this.observerName = subscriber;
        this.publisher = publisher;
        publisher.registerObserver(this);
    }

    @Override
    public void update(String title, String news)
    {
        this.news = title + "!!!" + news;
        System.out.println("=== " + observerName + " 수신 내용 ===\n" + news + "\n");
    }

}

 

 

그리고 Observer 인터페이스를 구현한 클래스들을 따로 만들고 update()를 정의해준다.

public class MessageSubscriberOne implements Observer
{
    @Override
    public void update(Message m)
    {
        System.out.println("1번 구독자가 메시지를 받았습니다 - " + m.getMessageContent());
    }
}
public class MessageSubscriberTwo implements Observer
{
    @Override
    public void update(Message m)
    {
        System.out.println("2번 구독자가 메시지를 받았습니다 - " + m.getMessageContent());
    }
}
public class MessageSubscriberThree implements Observer
{
    @Override
    public void update(Message m)
    {
        System.out.println("3번 구독자가 메시지를 받았습니다 - " + m.getMessageContent());
    }
}

마지막으로 메인을 만들어준다.

public class ObserverMain
{
    public static void main(String[] args)
    {
        MessageSubscriberOne s1 = new MessageSubscriberOne();
        MessageSubscriberTwo s2 = new MessageSubscriberTwo();
        MessageSubscriberThree s3 = new MessageSubscriberThree();

        MessagePublisher p = new MessagePublisher();

        p.attach(s1);
        p.attach(s2);

        p.notifyUpdate(new Message("첫 번째 메시지"));

        p.detach(s1);
        p.attach(s3);

        p.notifyUpdate(new Message("두 번째 메시지"));
    }
}

이걸 실행하면 아래와 같은 결과가 출력된다.

1번 구독자가 메시지를 받았습니다 - 첫 번째 메시지
2번 구독자가 메시지를 받았습니다 - 첫 번째 메시지
2번 구독자가 메시지를 받았습니다 - 두 번째 메시지
3번 구독자가 메시지를 받았습니다 - 두 번째 메시지

 

반응형

'개인 공부 > 디자인 패턴' 카테고리의 다른 글

빌더(Builder) 패턴이란?  (0) 2022.01.02
팩토리 패턴이란?  (0) 2021.10.05
[MVVM] MutableLiveData와 LiveData 차이  (0) 2021.04.24
MVC 패턴이란?  (0) 2020.11.27
자바 - 퍼사드 패턴(Facade Pattern)이란?  (0) 2020.11.25
Comments