The repository provides an example React application that uses Mobx state management library with Clean Architecture applied.
- Independent and reusable code units with separated concerns.
- Unified control and data flow.
- Testable code.
- Reduced cognitive overload when working with a codebase.
- Business Entity: Unit that encapsulates business rules and data.
- Business Rules and Data: The most general and high-level rules and data that are presentation-agnostic. They are the least likely to change when something external changes.
- Presentation (UI) Entity: Unit that encapsulates presentation rules and data.
- Presentation Rules and Data: Rules and data that represent how the UI is currently displayed.
- Store: An aggregate unit with set of business and/or presentation entities and/or gateways and/or other stores.
- State: The value of a store, which is often an object.
- Valid State: One of a finite number of store values that is conceptually considered valid.
- View Model: The state transformed into a form required for presentation in a view (e.g. a React Component).
- Gateway: Unit that provides external services (stateful, switches services, maps data, caches data).
- Selector: Unit that derives additional values from the state as needed.
- Transaction: Unit with a logic that transitions a store between two valid states.
- Effect: Unit with a logic that communicates with external systems and services through a gateway.
- Use Case: Unit that orchestrates the flow of data with the help of effects, transactions and selectors.
- Controller: An adapter unit that handles input from the view and converts it into a state change with the help of use cases (the public interface consists of methods decorated with
@action
). - Presenter: An adapter unit that handles the state and converts it into view models for the view with the help of selectors (the public interface consists of getters decorated with
@computed
).
Dependency graph of the code units.
Detailed dependency graph can be found here.
Dependency, data and events flow inside a React component
Architecture diagram
- OrderItemModel
- DeleteOrderTransactions
- TotalOrderItemQuantitySelectorOptimized
- TotalOrderItemQuantitySelector
- TotalOrderItemQuantitySelectorNotOptimized
- DeleteOrderUseCase
- DeleteOrderUseCaseWithInnerUnits
- DeleteOrderUseCaseWithExtractedUnits
- DeleteItemByIdUseCase
- DestroyModuleUseCase
- OrderItem
- OrderItemWithNullAdapter
- OrderItemWithOnlyDefinedAdapterInterface
- OrderItemWithCombinedAdapter
- OrderItemWithSplitAdapter
- OrderItemWithSplitExtractedAdapter
- OrderItemWithCombinedPropsObservableState
- OrderItemWithUseCase
- OrderItemWithSelector
- OrderItemController
- Orders
- DeleteOrderEffect
- HybridOrdersGateway
- LocalOrdersGateway
For the units implementation, it is suggested to use Cluster Lifecycle model described in this article, where generalization is important and mandatory step.
./src/modules/orders
├── api
│ ├── api.types.ts
│ ├── httpClient
│ │ └── httpClient.ts
│ ├── OrdersApi
│ │ ├── OrdersApi.factory.ts
│ │ ├── OrdersApi.ts
│ │ └── OrdersApi.types.ts
│ └── ServiceApi
│ ├── ServiceApi.ts
│ └── ServiceApi.types.ts
├── contexts
│ └── OrdersStoreContext.ts
├── drivers
│ └── OrdersDriver.ts
├── effects
│ └── DeleteOrderEffect
│ └── DeleteOrderEffect.ts
├── gateways
│ ├── HybridOrdersGateway
│ │ ├── HybridOrdersGateway.ts
│ │ ├── LocalOrdersGateway
│ │ │ └── LocalOrdersGateway.ts
│ │ └── RemoteOrdersGateway
│ │ ├── RemoteOrdersGateway.ts
│ │ ├── RemoteOrdersGateway.types.ts
│ │ └── RemoteOrdersGateway.utils.ts
│ └── RemoteServiceGateway
│ ├── RemoteServiceGatewayStub.ts
│ └── RemoteServiceGateway.ts
├── models
│ ├── OrderItemModel
│ │ ├── OrderItemModelCollection.ts
│ │ ├── OrderItemModel.factory.ts
│ │ └── OrderItemModel.ts
│ ├── OrderModel
│ │ ├── OrderModelCollection.ts
│ │ ├── OrderModel.factory.ts
│ │ └── OrderModel.ts
│ ├── OrdersCancelEffects.ts
│ └── OrdersPresentationModel
│ ├── OrdersPresentationModel.factory.ts
│ └── OrdersPresentationModel.ts
├── selectors
│ ├── ItemByIdSelector
│ │ └── ItemByIdSelector.ts
│ ├── OrderByIdSelector
│ │ └── OrderByIdSelector.ts
│ └── TotalOrderItemQuantitySelector
│ ├── TotalOrderItemQuantitySelectorNotOptimized.ts
│ ├── TotalOrderItemQuantitySelectorOptimized.ts
│ └── TotalOrderItemQuantitySelectorSingleton.ts
├── stores
│ ├── OrdersStore.factory.ts
│ └── OrdersStore.ts
├── transactions
│ └── DeleteOrderTransactions
│ └── DeleteOrderTransactions.ts
├── types
│ ├── aggregates
│ │ └── OrdersAggregate.ts
│ ├── entities
│ │ ├── OrderEntity
│ │ │ ├── OrderEntityCollection.ts
│ │ │ └── OrderEntity.ts
│ │ ├── OrderItemEntity
│ │ │ ├── OrderItemEntityCollection.ts
│ │ │ └── OrderItemEntity.ts
│ │ └── OrdersPresentationEntity.ts
│ ├── gateways
│ │ ├── OrdersGateway.ts
│ │ └── ServiceGateway.ts
│ └── OrdersCancelEffectCollection.ts
├── useCases
│ ├── DeleteItemByIdUseCase
│ │ ├── DeleteItemByIdUseCaseFactored.ts
│ │ └── DeleteItemByIdUseCasePlain.ts
│ ├── DeleteOrderUseCase
│ │ ├── DeleteOrderUseCaseWithExtractedUnits.ts
│ │ └── DeleteOrderUseCaseWithInnerUnits.ts
│ ├── DestroyModuleUseCase
│ │ └── DestroyModuleUseCase.ts
│ ├── LoadOrdersUseCase
│ │ └── LoadOrdersUseCase.ts
│ ├── PollingOrdersUseCase
│ │ └── PollingOrdersUseCase.ts
│ └── UpdateOrderUseCase
│ └── UpdateOrderUseCase.ts
└── views
└── containers
├── Order
│ ├── OrderAdapter
│ │ ├── OrderController.ts
│ │ └── OrderPresenter.ts
│ └── Order.tsx
├── OrderItem
│ ├── OrderItemWithCombinedAdapter
│ │ └── OrderItem.tsx
│ ├── OrderItemWithCombinedPropsObservableState
│ │ ├── OrderItemAdapter
│ │ │ ├── OrderItemController.ts
│ │ │ └── OrderItemPresenter.ts
│ │ └── OrderItem.tsx
│ ├── OrderItemWithNullAdapter
│ │ └── OrderItem.tsx
│ ├── OrderItemWithOnlyDefinedAdapterInterface
│ │ ├── OrderItem.tsx
│ │ └── OrderItem.types.tsx
│ ├── OrderItemWithSelector
│ │ ├── OrderItemAdapter
│ │ │ ├── OrderItemController.ts
│ │ │ ├── OrderItemPresenterWithExtractedSelector.ts
│ │ │ └── OrderItemPresenterWithInnerSelector.ts
│ │ └── OrderItem.tsx
│ ├── OrderItemWithSplitAdapter
│ │ └── OrderItem.tsx
│ ├── OrderItemWithSplitExtractedAdapter
│ │ ├── OrderItemAdapter
│ │ │ ├── OrderItemController.ts
│ │ │ └── OrderItemPresenter.ts
│ │ └── OrderItem.tsx
│ └── OrderItemWithUseCase
│ ├── OrderItemAdapter
│ │ ├── OrderItemControllerWithExtractedUseCase.ts
│ │ ├── OrderItemControllerWithInnerUseCase.ts
│ │ └── OrderItemPresenter.ts
│ └── OrderItem.tsx
└── Orders
├── Orders.tsx
└── Orders.utils.ts