React MVVM pattern with DDD
Introduction
This article is about how to implement MVVM pattern with DDD in React.
MVVM
MVVM is a pattern that separates the data model and business logic from the UI. It is a variation of MVC pattern. The difference between MVC and MVVM is that MVVM has a ViewModel layer that connects the Model and the View. But MVC does not have a ViewModel layer, so the Controller layer connects the Model and the View. The key of MVVM is the data binding between the View and the ViewModel.
Model
Model is a representation of data. It is a layer that contains business logic and data.
View : React Component
View is a layer that represents the UI. It is a layer that contains UI logic.
ViewModel : React Hook to manage state
ViewModel is a layer that connects the Model and the View. It is a layer that contains UI logic and data. Also, ViewModel tracks the changes of the Model and updates the View using React Hook.
DDD pattern (Domain Driven Design pattern)
DDD is a pattern that separates the domain logic from the application logic. It is a pattern that separates the domain logic from the application logic.
Domain
Domain is a layer that contains the business logic. It is a layer that contains the business logic.
Application
Application is a layer that contains the application logic. It is a layer that contains the application logic.
Implementation
Model
// src/model/counter.js
import { observable, action } from 'mobx'
export class Counter {
@observable count = 0
@action
increment() {
this.count++
}
@action
decrement() {
this.count--
}
}ViewModel
// src/viewModel/counter.js
import { observable, action } from 'mobx'
import { Counter } from '../model/counter'
export class CounterViewModel {
@observable counter = new Counter()
@action
increment() {
this.counter.increment()
}
@action
decrement() {
this.counter.decrement()
}
}View
// src/view/counter.js
import React from 'react'
import { observer } from 'mobx-react'
import { CounterViewModel } from '../viewModel/counter'
const CounterView = observer(({ viewModel }) => {
return (
<div>
<button onClick={() => viewModel.increment()}>+</button>
<span>{viewModel.counter.count}</span>
<button onClick={() => viewModel.decrement()}>-</button>
</div>
)
})
export default CounterViewApplication
// src/application/counter.js
import { CounterViewModel } from '../viewModel/counter'
export class CounterApplication {
constructor() {
this.viewModel = new CounterViewModel()
}
}Domain
// src/domain/counter.js
import { CounterApplication } from '../application/counter'
export class CounterDomain {
constructor() {
this.application = new CounterApplication()
}
}Main
// src/main.js
import React from 'react'
import ReactDOM from 'react-dom'
import { CounterDomain } from './domain/counter'
import CounterView from './view/counter'
const counterDomain = new CounterDomain()
ReactDOM.render(
<CounterView viewModel={counterDomain.application.viewModel} />,
document.getElementById('root')
)Conclusion
This article is about how to implement MVVM pattern with DDD in React.
Discussion