dev_swan 2023. 11. 10. 22:00

✏️ 옵저버 패턴

옵저버 패턴(Observer Pattern)은 주체가 어떤 객체의 상태 변화를 관찰하다가 상태 변화가 있을 때마다 메서드 등을 통해 옵저버 목록에 있는 옵저버들에게 변화를 알려주는 디자인 패턴입니다.

 

🔍 객체와 주체가 분리되어 있는 옵저버 패턴 (Classic Observer Pattern)

일반적인 옵저버 패턴으로 주체는 객체의 상태가 변경될 때 등록된 옵저버들에게 알림을 보내는 역할을 합니다. 옵저버는 객체의 상태 변화에 따라 전달되는 메서드 등을 기반으로 추가 변화 사항이 생기는 객체입니다. 주체와 옵저버는 서로 독립적으로 존재하며, 주체는 옵저버들에 대한 정보를 가지고 있습니다.

객체와 주체가 분리되어 있는 옵저버 패턴 - 면접을 위한 cs 전공지식 노트


🔍 객체와 주체가 합쳐진 옵저버 패턴 (Pull Model Observer Pattern)

객체가 상태 변경 시 직접 옵저버 객체의 메서드를 호출하며, 주체 객체가 옵저버 객체에 직접 알림을 보내는 방식으로 동작합니다. 이 경우 주체와 옵저버 간에 밀접하게 결합되어 있습니다. 주체는 옵저버에 대한 참조를 유지하며, 상태 변경 시 옵저버의 메서드를 호출하여 업데이트를 수행합니다.

객체와 주체가 합쳐진 옵저버 패턴 - 면접을 위한 CS 전공지식 노트


🔍 트위치의 옵저버 패턴

트위치의 옵저버 패턴은 객체와 주체가 합쳐진 옵저버 패턴의 변형으로, 사용자가 어떤 사람인 주체를 팔로우했다면 주체가 새로운 트윗을 올리게 될 경우 팔로워들에게 알림이 갑니다.

 

트위터의 옵저버 패턴 - 면접을 위한 CS 전공지식 노트


 

💻 자바스크립트의 옵저버 패턴

자바스크립트에서의 옵저버 패턴은 프록시 객체를 통해 구현할 수 있습니다.

더보기

💡 프록시 객체(Proxy Object)

프록시 객체는 어떠한 대상의 기본적인 동작의 작업을 가로챌 수 있는 객체를 뜻하며, 자바스크립트에서 프록시 객체는 프록시할 대상, 프록시할 대상의 동작을 가로채서 정의할 동작들이 정해져 있는 함수로 총 두 개의 매개변수를 가집니다.

const handler = {
    get: function (target, name, receiver) {
        return name === 'abc' ? `${target.a} ${target.b}` : target[name];
    },
};

const target = { a: "Asher's", b: 'vacation' };

const proxyObj = new Proxy(target, handler);
console.log(proxyObj.abc); // Asher's vacation

new Proxy로 선언한 객체의 a와 b라는 속성에 특정 문자열을 담아서 handler에 abc이라는 속성에 접근할 때는 a와 b를 합쳐서 문자열을 만들어 반환하도록 구현했습니다. 이렇게 proxyObj라는 값은 abc라는 속성을 선언하지 않았음에도 proxyObj.abc로 abc 속성에 접근하려고 할 때, 그 부분을 가로채 문자열을 만들어 반환하는 것을 확인할 수 있습니다.

const createReactiveObject = (target, callback) => {
    const proxy = new Proxy(target, {
        set(obj, prop, value) {
            if (value !== obj[prop]) {
                const prev = obj[prop];
                obj[prop] = value;
                callback(`${prop}가 ${prev} => ${value}로 승급에 성공했습니다.`);
            }
            return true;
        },
    });
    return proxy;
};

const age = {
    Asher: '실버',
};

const observerPattern = createReactiveObject(age, console.log);

observerPattern.Asher = '골드'; // Asher가 실버 => 골드로 승급에 성공했습니다.

위의 코드는 옵저버 패턴의 개념을 활용하여 객체의 속성 변경을 감지하고, 변경 사항을 콜백 함수를 통해 알림으로써 관찰자에게 전달하는 예제입니다.

 

createReactiveObject 함수는 주어진 대상 객체인 target과 변경 사항을 알리기 위한 콜백 함수를 인자로 받고 Proxy 객체를 생성하여 반환합니다.

 

이때, Proxy 객체는 주어진 대상 객체인 target을 감싸며, set 메소드를 오버라이드하여 속성 값이 변경될 때 동작을 추가합니다. 이렇게 함으로써 observerPattern에 할당된 Proxy 객체를 통해 age 객체의 속성 변경을 감지하고, 변경 사항을 콜백 함수를 통해 전달할 수 있게 됩니다.