Languages/디자인패턴
[Java] 옵저버(Observer) 패턴
yoon_seon
2023. 6. 12. 17:56
Observer 패턴이란?
옵서버 패턴은 객체의 상태 변화를 관찰하는 관찰자들, 즉 옵저버들의 목록을 객체에 등록하여 상태 변화가 있을 때마다 메서드 등을 통해 객체가 직접 목록의 각 옵저버에게 통지하도록 하는 디자인 패턴이다. 주로 분산 이벤트 핸들링 시스템을 구현하는 데 사용된다.
즉, 객체의 상태가 변할 경우 연관된 객체들에게 알린다 라는 의미의 패턴으로, 실생활에 비유하자면 구독을 예시로 들 수 있을 것 같다.
Observer 패턴 예시
구독자들이 유튜버의 새로운 소식에 대한 알림을 받는다 라는 주제로 예시를 들어보았다.
Youtuber 인터페이스
public interface Youtuber {
void addSubscriber(Subscriber subscriber);
void removeSubscriber(Subscriber subscriber);
void upload(String title);
}
- 구독자 추가, 구독자 삭제, 업로드의 역할을 정의하였다.
Subscriber 추상메서드
public abstract class Subscriber {
public void follow(Youtuber youtuber) {
youtuber.addSubscriber(this);
};
public void unFollow(Youtuber youtuber) {
youtuber.removeSubscriber(this);
};
public void alert(String msg) {
System.out.println("알림 : " + msg);
};
}
- 구독자는 유튜버를 팔로우할 수 있으며 자신을 구독자 리스트에 추가할 수 있다.
- 구독자는 유튜버를 언팔로우할 수 있으며 자신을 구독자 리스트에서 삭제할 수 있다.
- 구독자는 알림을 받을 수 있다.
Youtuber를 구현한 쯔양 클래스
public class Tzuyoung implements Youtuber {
private List<Subscriber> subscribers = new ArrayList<>();
@Override
public void addSubscriber(Subscriber subscriber) {
subscribers.add(subscriber);
}
@Override
public void removeSubscriber(Subscriber subscriber) {
subscribers.remove(subscriber);
}
@Override
public void upload(String title) {
subscribers.forEach(subscriber -> subscriber.alert("쯔양님의 새로운 소식이 있습니다. [" + title + "]"));
}
}
- 쯔양(유튜버)는 Subscriber(구독자)들의 리스트를 가지고 있다.
- 리스트에 구독자를 추가, 삭제할 수 있다.
- upload 메서드를 보면 유튜버가 새로운 소식을 업로드할 때 구독자들에게 알림을 보낸다.
Youtuber의 upload 메서드 호출 시 Subscriber의 alert()를 호출한다.
Subscriber를 확장한 Lee, Kim, Pack 클래스
public class Lee extends Subscriber {
@Override
public void alert(String msg) {
System.out.println("Lee 알림 : " + msg);
}
}
public class Kim extends Subscriber {
@Override
public void alert(String msg) {
System.out.println("Kim 알림 : " + msg);
}
}
public class Pack extends Subscriber {
@Override
public void alert(String msg) {
System.out.println("Pack 알림 : " + msg);
}
}
- 받은 알림을 출력한다.
예제 실행 Main 메서드
public static void main(String[] args) {
public static void observerExample() {
Tzuyoung tzuyoung = new Tzuyoung();
Kim kim = new Kim();
Lee lee = new Lee();
Pack pack = new Pack();
kim.follow(tzuyoung);
lee.follow(tzuyoung);
pack.follow(tzuyoung);
tzuyoung.upload("첫 번째 동영상");
kim.unFollow(tzuyoung);
tzuyoung.upload("두 번째 동영상");
}
}
- 구독자 kim, lee, pack은 유튜버 tzuyoung을 팔로우 한다.
- tzuyoung 유튜버가 소식을 업로드한다.
- 구독자 kim이 유튜버 tzuyoung을 언팔로우한다.
실행 결과

- tzuyoung 유튜버가 두 번째 소식을 업로드 할 때 구독을 취소한 kim은 알림 대상에서 제외되어 알림을 받지 않는 것을 확인할 수 있다.
이 처럼 객체의 상태가 변화될 때 연관된 객체들에게 알림을 보낼 수 있게 되었다. 이것이 옵저버 패턴이다.
코드를 자세히 보면 객체 간의 결합도가 낮은 것을 확인할 수 있으며 한 객체의 상태 변화가 다른 객체들에게 영향을 주지 않으면서 상호작용할 수 있는 유연한 구조를 구현할 수 있어서 시스템의 확장성과 유지보수성을 향상시킬 수 있다.