디자인패턴
디자인 패턴 - 옵저버 패턴
개발자 포비
2024. 12. 2. 11:51
객체 간 연관관계와 옵저버 패턴
객체는 서로 연관관계를 이루어 역할을 수행합니다. 예를 들어, A의 변화에 따라 B와 C가 저마다의 역할을 수행하는 것을 기대할 수 있습니다. 이러한 상황에서 개발자가 주의해야 할 점은 다음과 같습니다.
주의해야 할 사항
- A는 자신의 변화를 감지하는 객체들을 어떻게 관리할 것인가?
- A는 자신의 변화를 B와 C에 어떻게 알릴 것인가?
단순히 B와 C의 객체의 구현체를 A가 직접 들고 있다면 아래와 같은 문제가 발생합니다.
발생 가능한 문제점
- 강한 결합: A가 직접적으로 B와 C의 구현체를 들고 있으므로, 강한 결합을 가지게 되어 추후 유지보수가 어렵습니다.
- 확장성 부족: D라는 새로운 객체에 대해서도 처리해야 하는 경우, 코드가 비효율적으로 늘어나게 됩니다.
- 실수 발생 가능성: A가 변화가 발생했을 때, 변화를 감지하는 몇 객체에 대한 통지를 하지 않는 경우 실수가 발생할 수 있습니다.
옵저버 패턴의 필요성
이러한 문제를 해결하기 위해 옵저버 패턴을 사용합니다. 옵저버 패턴은 Subject
라는 변화가 감지되는 대상과 Observer
라는 변화를 감지하는 대상으로 구분되어 만들어집니다.
- 변화를 감지하는
Observer
객체는Subject
객체의 입장에서 변화 감지 객체를 추상화하여 통지할 수 있는 기능을 제공합니다. - 이는
Subject
객체의 확장성을 높이고 객체 간 결합성을 낮추어 OCP 원칙(Open/Closed Principle)에 부합합니다. - 변화 감지 대상은
Observer
라는 인터페이스를 구현하여Subject
객체에 등록되어 사용됩니다.
public interface Subject {
List<Observer> observers = new ArrayList<Observer>();
default void attach(Observer observer){
observers.add(observer);
}
default void detach(Observer observer){
observers.remove(observer);
}
default void notifyObservers(){
observers.forEach(Observer::update);
}
}
public interface Observer {
void update();
}
public class Content implements Subject {
public void update(){
System.out.println("SUBJECT UPDATED");
notifyObservers();
}
}
public class ObserverMain {
public static void main(String[] args) {
Content subject = new Content();
// Observer 객체에 Subject 객체를 등록한다.
// - 변화가 감지되는 경우에 사용하기 위한 목적
Observer observer1 = new ObserverImpl1(subject);
Observer observer2 = new ObserverImpl2(subject);
// 관심을 가지는 객체를 등록한다.
subject.attach(observer1);
subject.attach(observer2);
subject.update();
}
}