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, listener2는 stateObserver의 subscribe메서드를 사용해 구독할 수 있다.
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함수를 실행시켜준다. 즉 상태가 변경되면 모든 구독자들이 변경됨을 알 수 있다.