MVVM은 어떻게 등장하게 되었을까? view에서 처리하는게 많아져서 주도권을 view가 가져가게된것도 있고 controller에 view관련 코드가 많아져 controller가 비대해졌기 때문이라고 생각한다. 그래서 view에서 viewModel을 조작하는 MVVM이 등장한게 아닐까?
MVVM패턴에 대하여 학습하면서 나름대로 간단한 예제를 작성해보고 피드백을 받으면서 수정해보았다.
먼저 처음에 나름의 논리로 작성한 예제들이다. 기본적인 Model, View, Controller의 역할이 무엇인지 정의한것은 이전글에 작성하였다. 같은 팀원과 다양한 블로그들을 보면서 각 용어를 어떻게 정의하느냐에 따라 조금씩 다른 부분이 있다고 생각하여 미리 그 용어를 확실히 정의할 필요성을 느꼈다.
Model
const store = {
state: {
number: 0,
},
setState({ newState, changedState, fn }) {
this.state = newState;
if (fn === undefined) {
return;
}
fn(changedState);
},
};
export default store;
ViewModel
import store from "../Model/Store.js";
const counterViewModel = {
number: 0,
addCount({ fn }) {
store.setState({
newState: { ...store.state, number: store.state.number + 1 },
changedState: store.state.number + 1,
fn,
});
},
fetchCount({ fn }) {
const data = 5;
store.setState({
newState: { ...store.state, number: data },
changedState: data,
fn,
});
},
};
export default counterViewModel;
View
import counterViewModel from "../ViewModel/CounterViewModel.js";
const counterView = {
$count: document.querySelector(".count"),
render(number) {
this.$count.textContent = number;
},
fetchCount() {
counterViewModel.fetchCount({ fn: this.render.bind(this) });
},
onClickAdd() {
const $btn = document.querySelector(".btn");
$btn.addEventListener("click", () => {
counterViewModel.addCount({ fn: this.render.bind(this) });
});
},
};
export default counterView;
index.js
import counterView from "./VM/View/CounterView.js";
counterView.fetchCount();
counterView.onClickAdd();
이렇게 작성하고 팀원인 jamie에게 피드백을 요청하여 조언을 받았다.
1. 선언형 UI
View의 render를 작성하여서 index.js에서 사용할때 명령형으로 작성한 것을 선언형으로 변경하는것을 조언받았다. MVVM에서 view는 선언형 UI를 의미한다고 하는데 이게 MVVM패턴의 직접적인 요인은 아니라고 생각한다. 하지만 선언형 UI를 선호하게 된것은 선언형 UI가 훨씬 직관적이고 view가 늘어나면 그 view들을 관리할때 직관적인 코드들이 보기 편하고 보기 편하다는것은 유지보수할때 생산성을 높인다고 생각한다. 그래서 MVVM패턴에 영향을 주는 요소는 아니라도 선언형으로 변경하는것이 맞다고 생각한다.
2. observer 패턴
클라이언트input이 아닌경우 데이터가 변경될때(fetchCount) 자동으로 render되는것을 명령형이 아니라 observer 패턴을 이용하여 viewModel이 감지하게 하는것이다.
댓글