public class Client {
public static void main(String[] args) {
ChatServer chatServer = new ChatServer();
User user1 = new User(chatServer);
user1.sendMessage("디자인패턴", "이번엔 옵저버 패턴입니다.");
user1.sendMessage("롤드컵2021", "LCK 화이팅!");
User user2 = new User(chatServer);
System.out.println(user2.getMessage("디자인패턴"));
user1.sendMessage("디자인패턴", "예제 코드 보는 중..");
System.out.println(user2.getMessage("디자인패턴"));
}
}
위 Client 예제에서, "디자인패턴" topic 의 새로운 메세지를 주기적으로 있는지 확인하는 작업을 해야 새로운 메세지를 읽을 수 있다
이와 같이 주기적으로 요청해서 가져오는 방식을 폴링(Polling) 이라고 하는데,
폴링 메커니즘은 현재 구현에 적합하지 않을 수 있다
옵저버 패턴 다이어그램
Subject : 여러 옵저버들을 등록하거나 해지할 수 있는 기능을 제공
클라이언트는 Subject 를 사용해 여러 옵저버들을 등록하여 사용하고,
Subject 가 제공하는 메서드를 사용해 Subject 의 상태를 변경한다
상태가 변경되면 Subject 는 등록된 모든 옵저버들을 순회하면서
각 옵저버가 제공하는 특정한 메서드를 호출한다
Observer
인터페이스로 Subject 가 호출할 메서드를 가지고 있다
구현체 옵저버들은 해당 메서드를 구현하여 각기 다른 일을 수행하는 식
옵저버 패턴 2부 - 패턴 적용하기
After
Subscriber (Observer)
public interface Subscriber {
void handleMessage(String message);
}
User (ConcreteObserver)
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);
}
}
ChatServer (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 subscriber) {
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));
}
}
}
여러 옵저버들을 등록/해지 할 수 있어야 한다
누군가가 전송한 메세지는 상태를 변경한 것이라 보고,
sendMessage 메서드에서 해당 메세지를 Subscriber 들에게 broadcasting 한다
Client
public class Client {
public static void main(String[] args) {
ChatServer chatServer = new ChatServer();
User user1 = new User("keesun");
User user2 = new User("whiteship");
chatServer.register("오징어게임", user1);
chatServer.register("오징어게임", user2);
chatServer.register("디자인패턴", user1);
chatServer.sendMessage(user1, "오징어게임", "아.. 이름이 기억났어.. 일남이야.. 오일남");
chatServer.sendMessage(user2, "디자인패턴", "옵저버 패턴으로 만든 채팅");
chatServer.unregister("디자인패턴", user2);
chatServer.sendMessage(user2, "디자인패턴", "옵저버 패턴 장, 단점 보는 중");
}
}
옵저버 패턴 1부 - 패턴 소개
Before
옵저버 패턴 다이어그램
옵저버 패턴 2부 - 패턴 적용하기
After
Subscriber (Observer)
User (ConcreteObserver)
ChatServer (Subject)
sendMessage
메서드에서 해당 메세지를 Subscriber 들에게 broadcasting 한다Client