// 데이터와 비즈니스 로직을 담당하는 View
class UserModel {
constructor(name) {
this.name = name;
}
updateName(newName) {
this.name = newName;
}
}
// 사용자에게 표시되는 인터페이스를 담당하는 View
class UserView {
render(user) {
console.log(`사용자 이름: ${user.name}`);
}
}
class UserController {
constructor(model, view) {
this.model = model;
this.view = view;
}
handleNameChange(newName) {
this.model.updateName(newName);
this.view.render(this.model);
}
}
// 뷰를 표현하기 위한 상태와 행동을 캡슐화하는 View Model
class UserViewModel {
constructor(model) {
this.model = model;
}
get name() {
return this.model.name;
}
set name(newName) {
this.model.updateName(newName);
}
}
// 뷰와 모델 간의 중간 매개체로 동작하며 사용자 입력을 처리하고 모델에서 데이터를 가져와 뷰에 업데이트하는 Presenter
class UserPresenter {
constructor(model, view) {
this.model = model;
this.view = view;
}
handleNameChange(newName) {
this.model.updateName(newName);
this.view.render(this.model.name);
}
}
사용자 입력을 감지하고 모델과 뷰를 업데이트하는 역할
사용자 입력을 처리하고 모델과 뷰 간의 상호 작용을 조정하는 것이 주된 목적
뷰에 필요한 데이터를 제공하고, 뷰와 모델 사이의 중간 매개체 역할
뷰를 표현하기 위한 상태와 행동을 캡슐화하여 뷰와 모델 간의 결합을 완화하는 것이 주된 목적
사용자의 입력을 처리하고, 모델과 뷰 간의 중개자 역할
뷰와 모델 간의 결합을 느슨하게 유지하면서 사용자 입력을 처리하고 뷰를 업데이트하는 것이 주된 목적
1. 사용자의 action이 Controller로 들어온다.
2. Controller는 사용자의 action을 확인하고, Model을 업데이트
3. Controller는 Model을 나타내줄 View를 선택
4. View는 Model을 이용하여 화면을 나타냄
Controller가 Model을 업데이트하고 View를 선택하면 View가 Model을 나타냄
View와 Model 사이의 의존성이 높아 어플이케이션이 커질 수록 복잡하고 유지보수가 어려움
/src
/components
UserView.js
UserController.js
/models
UserModel.js
/views
App.js
import React from 'react';
import UserModel from '../models/UserModel';
import UserView from '../components/UserView';
class UserController extends React.Component {
constructor(props) {
super(props);
this.state = {
user: new UserModel('Ahhyeon'),
};
}
handleNameChange = (newName) => {
this.state.user.updateName(newName);
this.forceUpdate();
}
render() {
return (
<div>
<UserView user={this.state.user} />
<button onClick={() => this.handleNameChange('Ahyeon')}>Change Name</button>
</div>
);
}
}
export default UserController;
View와 Model의 의존성이 없음
캡슐화와 양방향 바인딩을 통해 View와 View Model의 의존성이 없음
각각의 부분이 독립적이기 때문에 모듈화하여 개발 가능
/src
/components
UserView.js
UserViewModel.js
/models
UserModel.js
/views
App.js
// View
import React from 'react';
class UserView extends React.Component {
render() {
// 양방향 바인딩
return <div>User Name: {this.props.userViewModel.name}</div>;
}
}
export default UserView;
// View Model
import React from 'react';
import UserModel from '../models/UserModel';
class UserViewModel extends React.Component {
constructor(model) {
super();
this.model = model;
}
get name() {
return this.model.name;
}
set name(newName) {
this.model.updateName(newName);
}
}
export default UserViewModel;
import React from 'react';
import UserModel from '../models/UserModel';
import UserView from '../components/UserView';
class UserPresenter extends React.Component {
constructor(props) {
super(props);
this.state = {
user: new UserModel('John Doe'),
};
}
handleNameChange = (newName) => {
this.state.user.updateName(newName); // View Model을 업데이트
this.forceUpdate();
}
render() {
return (
<div>
// View에 전달
<UserView userName={this.state.user.name} />
<button onClick={() => this.handleNameChange('Ahyeon')}>Change Name</button>
</div>
);
}
}
export default UserPresenter;
단방향 데이터 흐름을 유지하여 상태 관리를 간소화하는 데 중점을 둔 패턴
Flux 패턴을 기반으로 하되, 단순한 구조와 불변성을 강조하여 상태관리를 효과적으로 처리하는 데 중점을 둔 패턴
어플리케이션 전반에서 단일 객체 인스턴스만을 생성하고 이에 접근하는 패턴
객체 간 일대다 의존성을 정의하여 한 객체의 상태가 변경되면 종속 객체에 자동으로 알릴 수 있게 하는 패턴