dohun.log

[JS] 참조에 의한 전달과 옵저버 패턴 본문

Study/JavaScript

[JS] 참조에 의한 전달과 옵저버 패턴

dohun31 2022. 5. 31. 14:00

참조에 의한 전달

이전 글에서도 말했듯이 원시 값은 call by value이고, 객체 값은 call by reference이다.

function changePersonName(person) {
    person.name = 'hodun';
}

let person = {
    name: 'dohun',
    age: 22
};

console.log(person); // {name: 'dohun', age: 22}

changePersonName(person);

console.log(person); // {name: 'hodun', age: 22}

changePersonName함수에 매개변수로 person을 전달했을 때 person은 충분히 변경 가능하다는 얘기이다.

 

이처럼 객체가 변경되면 그 객체를 참조하는 모든 이들에게 객체가 변경됨을 알려주어야 한다.

 

옵저버 패턴

객체가 변경됐을 때 직접 추적하는 것이 아니라 옵저버가 구독자들에게 알려주는 방법을 사용한다.

Observer 클래스

class Observer {
    constructor() {
        this.listeners = new Set();
    }

    subscribe(observer) {
        this.listeners.add(observer);
    }

    notify() {
        this.listeners.forEach((listener) => {
            listener.notify();
        });
    }
}

subscribe(): 해당 옵저버를 구독할 수 있다.

notify(): 구독자 모두의 notirfy함수를 실행시킨다.

State 클래스

class State extends Observer {
    constructor() {
        super();
        this.state = {
            name: "dohun",
            age: 22,
        };
    }

    getState() {
        return this.state;
    }

    setState(newState) {
        this.state = { ...this.state, ...newState };
        this.notify();
    }
}

Oberser를 상속받는 클래스이다.

 

constructor(): super()를 통해서 부모 클래스인 Observer의 생성자를 먼저 호출하고 state 필드를 초기화시킨다.

getState(): 흔히 아는 getter이다.

setState(): 새로운 state인 newState를 받아 기존의 state를 갱신시킨다. 이후 Observer의 메서드인 notify를 호출해 State를 구독하는 구독자들에게 state가 변경됨을 알린다.

예시

const stateObserver = new State();

const listener1 = {
    id: "1",
    notify: () => {
        console.log("listener1 ::: 상태 변경");
    },
};

const listener2 = {
    id: "2",
    notify: () => {
        console.log("listener2 ::: 상태 변경");
    },
};

stateObserver.subscribe(listener1);
stateObserver.subscribe(listener2);

listener1, listener2stateObserversubscribe메서드를 사용해 구독할 수 있다.

console.log("getState::: ", stateObserver.getState());

console.log("setState::: change name dohun -> hodun");

stateObserver.setState({ name: "hodun" });

console.log("getState::: ", stateObserver.getState());

 이 코드를 실행하게 되면 결과는 다음과 같다.

코드 실행

stateObserver의 setState를 실행하면 Observer의 구독자들이 등록한 notify함수를 실행시켜준다. 즉 상태가 변경되면 모든 구독자들이 변경됨을 알 수 있다.

Comments