java/Design Pattern

옵저버 패턴 (observer pattern)

설기똥꼬 2023. 8. 23. 14:45

이번 포스팅에서는 GoF 디자인 패턴 중 하나인 옵저버 패턴에 대해 정리할 것이다.

예제를 직접 작성해보고 패턴의 로직을 익혀볼 것이다!

 

옵저버 패턴이란?

출처 : https://velog.io/@weekbelt/%EC%98%B5%EC%A0%80%EB%B2%84-Observer-%ED%8C%A8%ED%84%B4

소프트웨어 디자인 패턴 중 하나로, 객체 간의 일대다(one-to-many) 의존 관계를 정의하는 패턴이다.

이 패턴은 어떤 객체의 상태 변화가 발생했을 때 그 객체에 의존하는 다른 객체들에게 자동으로 알림을 보내고 상태 변화에 대한 처리를 할 수 있도록 해준다. 이는 객체 간의 결합도를 낮추고 유연한 구조를 만들어준다.

주로 분산 이벤트 핸들링 시스템을 구현하는 데 사용되어, Pub/Sub (발행/구독) 모델로도 알려져 있다.

ex) 발행자(Subject): 유튜브 채널, 관찰자(Observer): 구독자들

 

주요 요소

1. Subject (주체) 

  • 상태 변화를 감지하고, 옵저버들을 관리하는 객체이다.
  • 상태 변화가 발생하면 등록된 옵저버들에게 알림을 보낸다.

2. Observer (옵저버)

  • Subject의 상태 변화를 감지하고, 상태 변화에 대한 처리를 수행하는 인터페이스이다.

3. ConcreteSubject (구체적인 주체)

  • 실제 상태 변화가 일어나는 객체로서 Subject를 구현한 클래스이다.

4. ConcreteObserver (구체적인 옵저버)

  • 실제로 상태 변화를 감지하고 처리하는 객체로서 Observer를 구현한 클래스이다.

 

  • 옵저버 패턴에서는 한개의 관찰 대상자(Subject)와 여러개의 관찰자(Observer A, B, C)로 일 대 다 관계로 구성되어 있다.
  • 관찰 대상자(Subject)의 상태가 바뀌면 변경사항을 옵저버 한태 통보해준다. (notify)
  • 대상자로부터 통보를 받은 관찰자(Observer)는 값을 바꾸거나 삭제하는 등 적절히 대응한다. (update)
  • 관찰자(Observer)들은 언제든 관찰 대상자(Subject)의 그룹에서 추가/삭제 될 수 있다.

 

 

옵저버 패턴 예제

이번 옵저버 패턴 예시로 쓸 소재는 온라인 주문 알림 시스템이다. 온라인 쇼핑몰에서 주문이 들어왔을 때, 옵저버 패턴을 활용해 알림 시스템을 만들어볼 것이다.

 

 

관찰 대상자(Subject): 주문 클래스

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

public class Order {
    private List<Observer> observers = new ArrayList<>();
    private String status;

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

    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(this);
        }
    }

    public void setStatus(String status) {
        this.status = status;
        notifyObservers();
    }

    public String getStatus() {
        return status;
    }
}

 

관찰자(Observer) 인터페이스

public interface Observer {
    void update(Order order);
}

 

구체적인 관찰 대상자(ConcreteSubect): 주문 상태 변경

public class OrderNotification implements Observer {
    @Override
    public void update(Order order) {
        System.out.println("주문 상태 업데이트: " + order.getStatus());
    }
}

 

구체적인 관찰자(ConcreteObserver): 옵저버 등록 및 주문 상태 변화에 대한 처리

public class Main {
    public static void main(String[] args) {
        Order order = new Order();
        OrderNotification notification = new OrderNotification();

        order.attach(notification);

        order.setStatus("배송 중");
        order.setStatus("배송 완료");
    }
}

Order 객체와 OrderNotification 객체를 각각 생성한 후, 주문 상태의 변화에 따라 주문 알림이 옵저버에게 전달되고 출력된다.

order.attach(notification)과 같이 Order 클래스의 attach 메서드를 통하여 여러개의 관찰자 리스트에 추가한다.

관찰자 리스트에 포함된 객체들에 상태 변경 알림 setStatus를 통해 상태 변화를 전달하고 출력할 수 있다.

 

이로써 개념과 예제를 통해 옵저버 패턴에 대해 알아보았다.

객체의 느슨한 결합을 유지하면서 상태 변화를 처리할 수 있다는 점에서 확장 가능한 코드를 작성할 수 있었다.

주로 이벤트 핸들링이나 MVC 아키텍쳐에서 사용된다고 하니, 패턴 활용해서 나중에 코드 작성해보려고 한다!