Skip to content

Latest commit

 

History

History
82 lines (51 loc) · 7.22 KB

README.md

File metadata and controls

82 lines (51 loc) · 7.22 KB

📦 clean-architecture

A clean architecture example to implement testable and evolutive systems


✨ Features

A TypeScript implementation of the Clean Architecture specified by Robert C. Martin (Uncle Bob).

The Clean Architecture is an architectural pattern (a layered architecture) that enables the creation of loosely coupled and testable systems by enforcing a clear separation of concerns. This separation isolates the business rules from the details (such as frameworks and external dependencies like databases), making the system more maintainable and evolutive.

Following the "decompose by subdomain" pattern, a modular architecture has also been implemented to encapsulate and group all concerns from presentation to data per bounded context1. This modular monolith approach enables decision autonomy within a module boundary2 and the creation of self-contained systems centered around business capabilities3.
Furthermore, drawing inspiration from the Vertical Slice Architecture and the package by feature not by layer pattern, top-level directories within a module (excluding the shared folder) are centered around business features3 and, optionally, around actors for entities coupled to gateways. It allows not only to scream the application intent allowing better discoverability from the domain point of view but also to create cohesive and loosely-coupled components. Second-level directories and the shared directory are organized following the clean architecture layers to enforce/materialize the dependency rule and bring clarity about each layer scope.


🏗️ Architecture

Overview

TODO (architecture diagram with control flow following Clean architecture diagram (from the book)).

Components

Used building blocks (including DDD tactical patterns):

  • Entities
  • Value Objects
  • ...

Layers

Clean Architecture Layers

  • Enterprise Business Rules (Entities): TODO.
  • Application Business Rules (Use Cases): TODO.
  • Interface Adapters: Concrete implementation of ports folder that can include entity gateways, interface for data source implemented framework side, other repository/service gateways and GUI design pattern implementation (MVC, MVVM, MVP, ...).
  • Frameworks & Drivers: React views (and hooks), data source (including HttpDataSource to make fetch calls with error management, database client (Redis, SQL, MongoDB, ...), ...), ... TODO (include hosts (main component orchestrator)).
  • Hosts: Act like the configurator instance in the Hexagonal Architecture. Under the Clean Architecture, the host layer is the outermost layer. It includes the initial entry point of the system called the main component in the Clean Architecture book (in the "Main Component" chapter). This layer is not depicted in the diagram shown above. The main component is on the driver side (for example, Web UI, CLI, Back-end server, ...) and is responsible to instantiate inner layers.

Modules

TODO: package diagram / choosen feature split (catalog, ...) with slice across the different layers.

A special module: the Shared Kernel.

See documentation.


📚 Resources


✍️ Contribution

We're open to new contributions, you can find more details here.


📖 License

MIT


Footnotes

  1. In this repository, a bounded context is implemented by one module, so a bounded context is equivalent to a module here. However, it's not always the case since a bounded context is not strictly equivalent to a module. Indeed, while a module is a technical-oriented concept that defines logical boundaries in the code, a bounded context is a business-oriented one (domain-driven design tactical pattern) that represents a cohesive area of the business domain. A module is a technical enabler to implement a bounded context, which can contain one or multiple modules.

  2. By its standalone nature, a module enables more easily local decisions such as which architecture makes the most sense depending on the nature of the business and its complexity. For example, a module A with no or little business logic can implement a non-layered architecture (e.g. MVC, transaction scripts, ...) while a module B with more extensive and complex business rules can use a layered-like architecture to allow better separation of concerns (e.g. Clean Architecture, Onion Architecture, ...). In the repository, we're focusing on the clean architecture. Consequently, each module implements this architecture.

  3. A feature represents solution functionality that delivers business value while a capability represents larger solution functionality (generally a subdomain) grouping multiple features together in a cohesive way. 2