옵서버(Observer) 패턴은 객체 사이에 일대다 의존성을 정의하는 패턴입니다. 이 패턴은 한 객체의 상태가 변경되면 그 객체에 의존하는 다른 객체들에게 자동으로 알림을 보내 업데이트를 수행할 수 있게 합니다. 자바 코드를 통해 옵서버 패턴의 예시를 살펴보겠습니다.
가정해보겠습니다. 우리는 주식 시장에서 주식 가격의 변화를 추적하는 프로그램을 개발하고 있습니다. 주식 가격은 변동이 있을 때마다 다른 객체들에게 알림을 보내어 업데이트를 수행하고자 합니다. 옵서버 패턴을 사용하여 이를 구현해보겠습니다.
먼저, 주식 가격 변동을 추적할 주체인 Subject 인터페이스를 정의합니다:
public interface Subject {
void registerObserver(Observer observer);
void unregisterObserver(Observer observer);
void notifyObservers();
}
Subject 인터페이스에는 Observer 객체들을 등록하고 해제하는 메서드(registerObserver, unregisterObserver)와 등록된 Observer 객체들에게 알림을 보내는 메서드(notifyObservers)가 포함되어 있습니다.
다음으로, 주식 가격 변동을 감지할 옵서버를 나타내는 Observer 인터페이스를 정의합니다:
public interface Observer {
void update(double price);
}
Observer 인터페이스에는 update 메서드가 정의되어 있으며, 이 메서드는 주식 가격의 업데이트를 수신하는 역할을 합니다.
이제 Subject 인터페이스를 구현하는 구체적인 클래스인 StockMarket을 만들어보겠습니다:
import java.util.ArrayList;
import java.util.List;
public class StockMarket implements Subject {
private double price;
private List<Observer> observers;
public StockMarket() {
this.observers = new ArrayList<>();
}
public void setPrice(double price) {
this.price = price;
notifyObservers();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void unregisterObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(price);
}
}
}
StockMarket 클래스는 Subject 인터페이스를 구현하며, 주식 가격(price)과 등록된 Observer 객체들을 관리합니다. setPrice 메서드를 사용하여 주식 가격을 변경하면 등록된 Observer 객체들에게 알림을 보내 업데이트를 수행합니다.
마지막으로, Observer 인터페이스를 구현하는 구체적인 클래스인 StockViewer를 만듭니다:
public class StockViewer implements Observer {
private String name;
public StockViewer(String name) {
this.name = name;
}
@Override
public void update(double price) {
System.out.println(name + " received an update. New price: " + price);
}
}
StockViewer 클래스는 Observer 인터페이스를 구현하며, update 메서드를 오버라이딩하여 주식 가격의 업데이트를 수신합니다.
이제 옵서버 패턴을 사용하여 주식 시장에서 주식 가격 변동을 추적하는 예시 코드를 작성합니다:
public class Main {
public static void main(String[] args) {
// Subject 객체 생성
StockMarket stockMarket = new StockMarket();
// Observer 객체 생성
Observer viewer1 = new StockViewer("Viewer 1");
Observer viewer2 = new StockViewer("Viewer 2");
// Observer 객체를 Subject에 등록
stockMarket.registerObserver(viewer1);
stockMarket.registerObserver(viewer2);
// 주식 가격 변동
stockMarket.setPrice(100.0);
stockMarket.setPrice(105.0);
// Observer 객체를 Subject에서 해제
stockMarket.unregisterObserver(viewer1);
// 주식 가격 변동
stockMarket.setPrice(110.0);
}
}
위 예시에서는 StockMarket 객체를 생성하여 주식 가격 변동을 추적합니다. StockViewer 객체들을 생성하여 등록된 Observer로 사용하고, 주식 가격이 변경될 때마다 Observer들에게 업데이트를 전송합니다. registerObserver 메서드를 사용하여 Observer 객체들을 Subject에 등록하고, unregisterObserver 메서드를 사용하여 Subject에서 해제합니다.
실행 결과는 다음과 같습니다:
Viewer 1 received an update. New price: 100.0
Viewer 2 received an update. New price: 100.0
Viewer 1 received an update. New price: 105.0
Viewer 2 received an update. New price: 105.0
Viewer 2 received an update. New price: 110.0
이 예시에서는 옵서버 패턴을 사용하여 주식 가격 변동을 추적하고 Observer 객체들에게 알림을 보냈습니다. Subject와 Observer의 인터페이스를 정의하고 구체적인 클래스를 구현함으로써 객체들 간의 느슨한 결합을 유지하며 업데이트를 수행할 수 있게 되었습니다.