티스토리 뷰

디자인 패턴

19. 옵저버 패턴

jin-park 2022. 2. 11. 11:22

1. 옵저버 패턴?

  • 다수의 객체가 특정 객체 상태 변화를 감지하고 알림을 받는 패턴
    • 발행 publish 구독 subscribe 패턴을 구현

다이어그램

  1. subject > 여러 옵저버들을 등록, 해지 기능 제공
    1. 클라이언트는 서브젝트에 옵저버 등록, 서브젝트의 상태 변경
    2. 서브젝트는 상태가 변경되면 자신에게 등록된 모든 옵저버를 순회하면서 옵저버가 제공하는 메소드 호출
  2. observer > interface 
    1. observer가 해야할 일, 규약
  3. concrete observer > observer 구현체

2. 적용하기

  • 간단한 채팅 소스로 예시 작성

2.1. 적용전

  • 주체가 주기적으로 요청해서 가져옴.
public class ChatServer {
 
    private Map<String, List<String>> messages;
 
    public ChatServer() {
        this.messages = new HashMap<>();
    }
 
 
    public void add(String subject, String message) {
        if (messages.containsKey(subject)) {
            messages.get(subject).add(message);
        } else {
            List<String> messageList = new ArrayList<>();
            messageList.add(message);
            messages.put(subject, messageList);
        }
    }
 
    public List<String> getMessage(String subject) {
        return messages.get(subject);
    }
}
public class User {
 
    private ChatServer chatServer;
 
    public User(ChatServer chatServer) {
        this.chatServer = chatServer;
    }
 
 
    public void sendMessage(String subject, String message) {
        chatServer.add(subject, message);
    }
 
    public List<String> getMessage(String subject) {
        return chatServer.getMessage(subject);
    }
}
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("디자인패턴"));

2.2. 패턴 적용 후

  • subject → ChatServer
  • observer → Subscriber
  • concrete observer → User
public interface Subscriber {
    void handleMessage(String message);
}
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);
    }
}
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));
        }
    }
 
}
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("디자인패턴"));

3. 장점과 단점

3.1. 장점

  • 상태를 변경하는 객체 publisher 와 변경을 감지하는 객체 subsriber 의 관계를 느슨하게 유지할 수 있다.
  • subject의 상태 변경을 주기적으로 조회하지 않고 자동으로 감지할 수 있다.
  • 런타임에 옵저버를 추가하거나 제거할 수 있다.

3.2. 단점

  • 복잡도가 증가한다.
  • 다수 observer 객체를 등록 이후 해지 않는다면 memory leak 발생할 수도 있다.
    • map에 옵저버가 등록되어있어 gc 대상에서 제외됨.

위글은 인프런의 코딩으로 학습하는 GoF의 디자인 패턴강의를 정리하였습니다.

백기선님의 수락으로 정리하였으며 더 자세한 내용은 강의를 수강하시기 바랍니다.

https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4/dashboard

 

코딩으로 학습하는 GoF의 디자인 패턴 - 인프런 | 강의

디자인 패턴을 알고 있다면 스프링 뿐 아니라 여러 다양한 기술 및 프로그래밍 언어도 보다 쉽게 학습할 수 있습니다. 또한, 보다 유연하고 재사용성이 뛰어난 객체 지향 소프트웨어를 개발할

www.inflearn.com

 

'디자인 패턴' 카테고리의 다른 글

21. 전략 패턴  (0) 2022.02.11
20. 상태(State) 패턴  (0) 2022.02.11
18. 메멘토 패턴  (0) 2022.02.10
17. 중재자 패턴  (0) 2022.02.10
16. 이터레이터 패턴  (0) 2022.02.10
댓글