Clean Architecture
This gem provides helper interfaces and classes to assist in the construction of application with Clean Architecture, as described in Robert Martin's seminal book.
Installation
Add this line to your application's Gemfile:
gem 'clean-architecture'
And then execute:
$ bundle install
$ bundle binstubs clean-architecture
Usage
The intention of this gem is to help you build applications that are built from the use case down, and decisions about I/O can be deferred until the last possible moment. It relies heavily on the duckface-interfaces gem to enforce interface implementation.
Use cases as an organisational principle
Uncle Bob suggests that your source code organisation should allow developers to easily find a listing of all use cases your application provides. Here's an example of how this might look in a Rails application.
- lib
- my_banking_application
- use_cases
- retail_customer_opens_bank_account.rb
- retail_customer_makes_a_deposit.rb
- ...
Clean architecture principles
- The code that manages your inputs (e.g. a Rails controller) instantiates a persistence layer
object
- Suggest: a class that implements both the
Persistence
interface and your own persistence interface
- Suggest: a class that implements both the
persistence = ActiveRecordPersistence.new
- The code that manages your inputs (e.g. a Rails controller) instantiates a use case actor
object
- Suggest: a class that implements the
UseCaseActor
interface
- Suggest: a class that implements the
use_case_actor = MyUseCaseActorAdapter.new(devise_current_user)
- The code that manages your inputs (e.g. a Rails controller) instantiates a use case input port
object
- Suggest: a class that implements the
BaseParameters
interface - Suggest: implement the
AuthorizationParameters
interface if you want to make authorization part of your use case logic - Suggest: implement the
TargetedParameters
if your use case operates on a single object - Suggest: use the
TargetedParameters
entity for an out-of-the-box class that gives you all of these
- Suggest: a class that implements the
input_port = CleanArchitecture::Entities::TargetedParameters.new(
use_case_actor,
TargetActiveRecordClass.find(params[:id]),
strong_params,
persistence,
other_settings_hash
)
- The code that manages your inputs (e.g. a Rails controller) instantiates a use case object
- Suggest: a class that implements the
UseCase
interface
- Suggest: a class that implements the
use_case = MyBankingApplication::UseCases::RetailCustomerMakesADeposit.new(input_port)