자바 옵저버 디자인 패턴 소개

디자인 패턴은 객체 지향 프로그래밍에서 자주 사용되는 문제를 해결하기 위한 일종의 템플릿입니다. 디자인 패턴은 다양한 종류가 있지만, 이번에는 객체 간의 일대다 종속성을 다루는 자바 옵저버 디자인 패턴을 소개하겠습니다.

자바 옵저버 디자인 패턴은 객체의 상태가 변경될 때, 이를 관찰하고자 하는 객체들에게 자동으로 알림을 보내는 디자인 패턴입니다. 이 패턴은 한 객체가 다른 객체들과 약하게 결합되어 있고, 서로 간의 상호작용이 필요한 경우에 유용합니다. 자바 옵저버 디자인 패턴은 일대다 종속성을 다루는 데 효과적입니다.

옵저버 디자인 패턴은 MVC(Model-View-Controller) 패턴에서도 사용됩니다. 모델은 옵저버가 되어 뷰와 컨트롤러에게 상태 변경을 알리는 역할을 합니다. 뷰와 컨트롤러는 옵저버 역할을 하여 모델의 상태 변경을 감지하고, 화면에 보여주거나 사용자 입력을 처리합니다.

Observer design pattern

객체 간 일대다 종속성 이해하기

객체 간의 일대다 종속성은 한 객체가 여러 개의 객체에게 종속되어 있는 상황입니다. 예를 들어, 한 객체가 변경되면 다른 여러 객체들도 이를 알아야 하는 경우가 있습니다. 이럴 때, 일일이 각 객체에게 알리는 것은 번거로우며, 유지보수도 어려워집니다.

자바 옵저버 디자인 패턴은 이러한 문제를 해결하기 위해 객체 간의 일대다 종속성을 다룹니다. 이 패턴은 한 객체가 변경되면, 이를 관찰하고자 하는 모든 객체에게 자동으로 알림을 보내는 구조를 가지고 있습니다. 이를 통해, 객체 간의 결합도를 낮출 수 있고, 유연성과 확장성을 높일 수 있습니다.

자바 옵저버 디자인 패턴 구현 방법

자바 옵저버 디자인 패턴의 구현 방법은 크게 두 가지입니다. 첫 번째 방법은 자바 내장 인터페이스인 Observer와 Observable을 사용하는 방법입니다. 두 번째 방법은 직접 옵저버와 서브젝트를 구현하는 방법입니다.

Observer와 Observable 인터페이스 사용하기

자바에서는 옵저버 패턴을 위해 기본적으로 Observer와 Observable 인터페이스를 제공합니다. Observer는 관찰 대상 객체에서 상태를 알리는 메서드를 호출하는 인터페이스입니다. Observable은 관찰 대상 객체의 상태를 알리는 역할을 합니다.

import java.util.Observable;
import java.util.Observer;

public class WeatherData extends Observable {
    private float temperature;
    private float humidity;
    private float pressure;

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

    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }

    public float getTemperature() {
        return temperature;
    }

    public float getHumidity() {
        return humidity;
    }

    public float getPressure() {
        return pressure;
    }
}

public class CurrentConditionsDisplay implements Observer {
    private float temperature;
    private float humidity;

    public void update(Observable obs, Object arg) {
        if (obs instanceof WeatherData) {
            WeatherData weatherData = (WeatherData) obs;
            this.temperature = weatherData.getTemperature();
            this.humidity = weatherData.getHumidity();
            display();
        }
    }

    public void display() {
        System.out.println("Current conditions: " + temperature
            + "F degrees and " + humidity + "% humidity");
    }
}

직접 옵저버와 서브젝트 구현하기

Observer와 Observable 인터페이스를 사용하지 않고, 직접 옵저버와 서브젝트 클래스를 구현하는 방법도 있습니다.

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

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

public class WeatherData implements Subject {
    private ArrayList observers;
    private float temperature;
    private float humidity;
    private float pressure;

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

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

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

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

    public void measurementsChanged() {
        notifyObservers();
    }

    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }
}

public class CurrentConditionsDisplay implements Observer {
    private float temperature;
    private float humidity;
    private Subject weatherData;

    public CurrentConditionsDisplay(Subject weatherData) {
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }

    public void update(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        display();
    }

    public void display() {
        System.out.println("Current conditions: " + temperature
            + "F degrees and " + humidity + "% humidity");
    }
}

자바 옵저버 디자인 패턴의 장단점 분석

자바 옵저버 디자인 패턴의 장점은 다음과 같습니다.

  • 객체 간의 결합도를 낮출 수 있습니다.
  • 유연성과 확장성을 높일 수 있습니다.
  • 상태 변경에 대한 알림을 자동으로 보내므로, 일일이 알리는 번거로움을 줄일 수 있습니다.

하지만, 자바 옵저버 디자인 패턴의 단점도 있습니다.

  • 관찰 대상 객체와 옵저버 객체 간의 인터페이스 설계가 잘못될 경우, 코드의 복잡도가 증가할 수 있습니다.
  • 옵저버 객체가 많아질 경우, 알림을 보내는 시간이 증가하여 성능 문제가 발생할 수 있습니다.

이러한 단점을 극복하기 위해서는, 옵저버 패턴을 적절하게 사용하는 것이 중요합니다. 따라서, 객체 간의 일대다 종속성을 다루는 자바 옵저버 디자인 패턴은 객체 지향 프로그래밍에서 매우 유용한 패턴 중 하나입니다.

+ Recent posts