상태의 변경을 감지하고, 지켜보는 패턴. 여러 개의 객체들이 한개의 상태변화를 감지하고 반응할 때 적용한다.
pubslish - subscribe
를 구현하기에 적합하다.
public class Client {
public static void main(String[] args) {
ChatServer chatServer = new ChatServer();
User user1 = new User(chatServer);
user1.sendMessage("design pattern", "observer");
user1.sendMessage("2022", "test");
User user2 = nwe User(chatServer);
user1.sendMessage("design pattern", "code");
}
}
public interface Subscriber {
void handleMessage(String message);
}
public class User implements Subscriber {
private String name;
@Override
public void handleMessage (String meassage); {
}
//getter, constructor
}
public class ChatServer {
private Map<String, List<Subscribe> subscribers = new HashMap<>();
public void register(String subject, Subscriber subscriber) {
if(subscribers.containsKey(subject)) {
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 subscriber) {
if(subscribers.containsKey(subject)) {
subscribers.get(subject).remove(subscriber);
}
}
public void sendMessage (User user, String subject, String message) {
String userMessage = user.getName() + ": " + message;
if(subscribers.containsKey(subject)) {
this.subscribers.get(subject).forEach(s -> s.handleMessage(userMessage));
}
}
}
public class Cilent {
public static void main(String[] args) {
ChatServer chatServer = new ChatServer();
User user1 = new User("user1");
User user2 = new User("user2");
chatServer.register("aaa", user1);
chatServer.register("aaa", user2);
chatServer.register("bbb", user1);
chatServer.sendMessage(user1, "aaa", "aaa11");
chatServer.sendMessage(user2, "bbb", "bbb11");
}
}
publisher
와 변경을 감지하는 객체 subscriber
의 관계를 느슨하게 유지할 수 있다.Subject
의 상태 변경을 주기적으로 조회하지 않고 자동으로 감지할 수 있다.Observer
객체를 등록 이후 해지하지 않으면 메모리 누수가 발생할 수 있다.Java 9
부터는 사용을 권장하지 않는다. 대신 PropertyChangeListener
를 사용한다.
Processor
, Publisher
, Subscriber
과 onComplete
를 확장하여 사용할 수 있다.
EventPublisher
이다.