행동 패턴: 옵저버 패턴

xellos·2022년 4월 14일
0

디자인 패턴

목록 보기
18/20

소개

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

1) 장점

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

2) 단점

  1. 복잡도가 증가한다.
  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, "디자인 패턴", "옵저버 패턴 장・딘점");
    }
}

0개의 댓글