소개
- 다수의 객체가 특정 객체 상태변화를 감지하고 알림을 받는 패턴이다.
- 발행(PUBLISH) - 구독(SUBSCRIBE) 패턴을 구현할 수 있다.

1) 장점
- 상태를 변경하는 객체(PUBLISHER)와 변경을 감지하는 객체(SUBSCRIBER)의 관계를 느슨하게 유지할 수 있다.
- Subject의 상태 변경을 주기적으로 조회하지 않고 자동으로 감지할 수 있다.
- 런타임에 옵저버를 추가하거나 제거할 수 있다.
2) 단점
- 복잡도가 증가한다.
- 다수의 OBSERVER 객체를 등록이후 해제하지 않는다면 MEMORY LEAK이 발생할 수 있다.
구현
1) Observer 인터페이스 정의
public interface Subsriber {
void handleMessage(String message);
}
2) 인터페이스를 구현하는 구체 클래스 정의
public class User implements Subscriber {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public void handleMessage(String message) {
System.out.println(message);
}
}
3) Subject 구현
public class ChatServer {
private Map<String, List<Subscriber>> subscribers = new HashMap<>();
public void register(String subject, Subscriber subscriber) {
if(this.subscribers.containsKey(subject)) {
this.subscribers.get(subject).add(subscriber);
} else {
List<Subscriber> list = new ArrayList<>();
list.add(subscriber);
this.subscribers.put(subject, list);
}
}
public void unregister(String subject, Subscriber subsriber) {
if(this.subscribers.containsKey(subject)) {
this.subscribers.get(subject).remove(subscriber);
}
}
public void sendMessage(User user, String subject, String message) {
if(this.subscribers.containsKey(subject)) {
String userMessage = user.getName() + " : " + message;
this.subscribers.get(subject).forEach(s -> s.handleMessage(userMessage));
}
}
}
사용
public class Client {
public static void main(String[] args) {
ChatServer chatServer = new ChatServer();
User user1 = new User("xellos");
User user2 = new User("alpha");
chatServer.register("오징어 게임", user1);
chatServer.register("오징어 게임", user2);
chatServer.register("디자인 패턴", user1);
chatServer.register("디자인 패턴", user2);
chatServer.sendMessage(user1, "오징어 게임", "아.. 이름이 기억났어");
chatServer.sendMessage(user2, "디자인 패턴", "옵저버 패턴");
chatServer.unregister("디자인 패턴", user2);
chatServer.sendMessage(user, "디자인 패턴", "옵저버 패턴 장・딘점");
}
}