DESIGN PATTERN

[디자인패턴] 옵저버패턴(Observer Pattern) 이란? - 개발자 배찌

개발자 배찌 2022. 4. 15. 16:13
728x90

😀옵저버패턴 (observer pattern)
다수의 객체가 특정객체 상태변화를 감지하고 알림을 받는 패턴

😀옵저버 패턴의 장점
상태를 변경하는 객체와 변경을 감지하는 객체(observer)의 관계를 느슨하게 유지할 수 있다.
상태 변경을 주기적으로 조회하지 않고 자동으로 감지할 수 있다.

😀옵저버 패턴의 단점
복잡도가 증가한다.
다수의 observer객체를 등록 이후 해지하지 않으면, 메모리누수 발생할 수 있다.

😀코드로 알아보기!
ChatServer.java

package study.observerPattern.code1;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ChatServer {
    //여러 옵저버들을 등록하거나 해지할수 있어야 함.
    //옵저버들을 특정한 주제들로 묶어놓을것이기 때문에 map 사용
    private Map<String, List<Subscriber>> 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){
        if(this.subscribers.containsKey(subject)){
            String userMessage = user.getName() + " : " + message ;
            this.subscribers.get(subject).forEach(s->s.handleMessage(userMessage));
        }
    }

}


Subscriber.java

package study.observerPattern.code1;

public interface Subscriber {
    void handleMessage(String message);
}


User.java

package study.observerPattern.code1;

import lombok.extern.slf4j.Slf4j;

@Slf4j
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) {
        log.info(message);
    }
}


ObserverPatternTest.java

package study.observerPattern;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import study.observerPattern.code1.ChatServer;
import study.observerPattern.code1.User;

@Slf4j
public class ObserverPatternTest {
    @Test
    void code1test(){
        ChatServer chatServer = new ChatServer();
        User user1 = new User("jiyoung");
        User user2 = new User("gildong");

        chatServer.register("자바스터디", user1);
        chatServer.register("디비스터디", user1);

        chatServer.register("디비스터디", user2);

        chatServer.sendMessage(user1, "자바스터디", "자바스터디를 시작하자!!");
        chatServer.sendMessage(user2, "디비스터디", "디비스터디를 시작하자!!");

        chatServer.unregister("디비스터디", user1);

        chatServer.sendMessage(user2, "디비스터디", "옵저버 패턴 장/단점 보는중");



    }
}


결과화면

jiyoung : 자바스터디를 시작하자!!
gildong : 디비스터디를 시작하자!!
gildong : 디비스터디를 시작하자!!
gildong : 옵저버 패턴 장/단점 보는중
gildong : 옵저버 패턴 장/단점 보는중