준비하는 대학생

[Design Pattern] Observer Pattern(옵저버 패턴) 본문

Programming/Design pattern

[Design Pattern] Observer Pattern(옵저버 패턴)

Bangii 2023. 3. 29. 23:47

Observer Pattern 개요

Observer Pattern은 객체 간에 일대다 관계를 정의하는 디자인 패턴 중 하나입니다. 이 패턴은 객체들 사이에 느슨한 결합을 제공하며, 객체의 상태 변화에 대한 다른 객체들의 자동 업데이트를 가능하게 합니다.

Observer Pattern은 Subject(주체)와 Observer(관찰자)로 구성됩니다. Subject 객체는 상태를 가지며, 상태가 변경되었을 때 Observer들에게 알림을 보냅니다. Observer 객체는 Subject 객체의 상태를 관찰하며, 상태가 변경될 때마다 업데이트를 받습니다.

Observer 패턴은 다음과 같은 구성 요소로 이루어져 있습니다.

  1. Subject: Observer 객체들을 관리하는 객체로, Observer를 추가, 제거, 알림을 보내는 기능을 제공합니다.
  2. Observer: Subject 객체의 상태 변경을 감시하는 객체로, Subject의 상태가 변경될 때마다 업데이트되는 메서드를 구현합니다.
  3. ConcreteSubject: 실제 상태를 저장하고, Observer에게 상태 변경을 알리는 구체적인 Subject입니다.
  4. ConcreteObserver: 실제 Observer 객체로, ConcreteSubject의 상태 변경을 감지하고, 적절한 행동을 수행합니다.

예를 들어, 온도계를 생각해보겠습니다. 온도계는 Subject 역할을 하며, 온도가 변경될 때마다 Observer 역할을 하는 디스플레이에 온도 정보를 전달합니다. 이러한 관계는 다른 Observer 객체를 추가하거나 제거함으로써 동적으로 변경될 수 있습니다.

자바에서 Observer Pattern을 구현하는 방법은 다음과 같습니다.

Java를 사용한 Observer Pattern 예제

온라인 쇼핑몰에서 새 상품이 등록되면 관심 고객에게 알림을 보내는 시스템을 Observer 패턴을 활용해 구현해보겠습니다.

1. Subject 인터페이스 만들기

Subject 인터페이스는 Subject 역할을 하는 객체가 구현해야 하는 메서드를 정의합니다. 이 인터페이스는 다음과 같이 구성됩니다.

public interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

2. Observer 인터페이스 만들기

Observer 인터페이스는 Observer 역할을 하는 객체가 구현해야 하는 메서드를 정의합니다. 이 인터페이스는 다음과 같이 구성됩니다.

public interface Observer {
    void update(float temperature);
}

 

3. Subject 클래스 만들기

Subject 클래스는 Subject 인터페이스를 구현하며, 상태를 저장하고 Observer 객체들을 등록하고 삭제하는 메서드를 구현합니다. 이 클래스는 다음과 같이 구성됩니다.

public class WeatherData implements Subject {
    private List<Observer> observers;
    private float temperature;

    public WeatherData() {
        observers = new ArrayList<>();
    }

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

    public void removeObserver(Observer observer) {
        int i = observers.indexOf(observer);
        if (i >= 0) {
            observers.remove(i);
        }
    }

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

    public void setTemperature(float temperature) {
        this.temperature = temperature;
        measurementsChanged();
    }

    public void measurementsChanged() {
        notifyObservers();
    }
}

4. Observer 클래스 만들기

Observer 클래스는 Observer 인터페이스를 구현하며, Subject 객체의 상태가 변경될 때마다 업데이트를 받는 메서드를 구현합니다. 이 클래스는 다음과 같이 구성됩니다.

public class CurrentConditionsDisplay implements Observer {
    private float temperature;
    
    public void update(float temperature) {
        this.temperature = temperature;
        display();
    }

    public void display() {
        System.out.println("Current temperature: " + temperature);
    }
}

5. 실행 코드 작성하기 실행 코드는 다음과 같이 작성됩니다.

public static void main(String[] args) {
    WeatherData weatherData = new WeatherData();

    CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay();
    weatherData.registerObserver(currentDisplay);

    weatherData.setTemperature(80);
    weatherData.setTemperature(82);
}

위 코드는 WeatherData 객체를 생성하고, CurrentConditionsDisplay 객체를 생성하여 등록한 후, 온도를 변경하는 예시입니다. 온도가 변경될 때마다 CurrentConditionsDisplay 객체의 update() 메서드가 호출되어 온도가 출력됩니다.

이러한 Observer Pattern은 상태 변화를 처리하는 다른 패턴과 결합하여 더욱 복잡한 시스템을 구성할 수 있습니다. 또한, Observer 객체들을 동적으로 추가하거나 제거함으로써 유연성을 제공하며, 객체 간의 결합도를 낮추는 장점이 있습니다.

 

Observer Pattern의 클래스 다이어그램

아래는 Observer Pattern의 클래스 다이어그램입니다.

 

위 다이어그램에서 Subject와 Observer는 인터페이스로 정의되어 있습니다. 이러한 인터페이스를 구현하는 클래스들은 실제로 객체들의 상호작용을 처리합니다. ConcreteSubject는 Subject 인터페이스를 구현한 클래스로, 상태 변화를 처리하고 Observer들에게 알림을 보냅니다. ConcreteObserver는 Observer 인터페이스를 구현한 클래스로, Subject 객체의 상태 변화를 감지하고 업데이트를 수행합니다.

Observer Pattern은 다음과 같은 경우에 적합합니다.

  • 객체 간의 결합도를 낮추고 유연성을 제공해야 할 때
  • 상태 변화에 대한 다른 객체들의 자동 업데이트가 필요할 때
  • 한 객체의 상태 변화에 대한 여러 객체들의 반응이 필요할 때

Observer Pattern은 자바의 GUI 프레임워크인 Swing에서도 사용됩니다. 예를 들어, JButton 클래스는 ActionListener 인터페이스를 구현한 객체들의 등록을 허용하며, JButton 객체가 클릭될 때마다 등록된 ActionListener 객체들의 actionPerformed() 메서드가 호출됩니다. 이러한 방식으로 버튼 클릭 이벤트를 처리할 수 있습니다.

Observer Pattern은 객체 지향 설계의 기본 개념 중 하나인 "단일 책임 원칙"을 따르며, 코드의 재사용성과 확장성을 높일 수 있는 강력한 패턴 중 하나입니다.

Observer Pattern은 중요한 디자인 패턴 중 하나이며, 실제로 많은 소프트웨어 시스템에서 사용됩니다. 이 패턴을 이해하고 활용하는 것은 객체 지향 설계 및 소프트웨어 개발에서 중요한 역할을 합니다.

Observer Pattern을 구현할 때 주의해야 할 점 중 하나는 Subject 객체의 상태를 변경하는 메서드가 호출될 때, Observer 객체들의 update() 메서드가 항상 호출되도록 하는 것입니다. 이를 위해서는 Subject 클래스에서 measurementsChanged()와 같은 메서드를 정의하여 Observer 객체들에게 알림을 보내는 방법을 구현해야 합니다.

또한, Observer Pattern에서는 Observer 객체가 Subject 객체의 상태를 직접적으로 변경하는 것이 아니라, Subject 객체가 Observer 객체들의 update() 메서드를 호출하여 상태를 업데이트하도록 해야 합니다. 이를 통해 객체 간의 결합도를 낮출 수 있으며, 유연성과 확장성을 높일 수 있습니다.

마지막으로, Observer Pattern은 다른 디자인 패턴과 결합하여 더욱 복잡한 시스템을 구성할 수 있습니다. 예를 들어, MVC(Model-View-Controller) 패턴에서는 Observer Pattern을 사용하여 모델(Model)과 뷰(View) 사이의 상호작용을 처리합니다.

이상으로 Observer Pattern에 대해 알아보았습니다. 이 패턴을 활용하여 객체 지향적인 설계와 유지보수 가능한 소프트웨어 시스템을 구축할 수 있습니다.

 
Comments