README.md in clean-architecture-4.0.1 vs README.md in clean-architecture-5.0.1
- old
+ new
@@ -95,11 +95,11 @@
> Always depend on or derive from a stable abstraction, rather than a volatile concrete class
We satisfy the OCP, LSP & DIP by following these rules:
-- We create a clean boundary between our business logic, our persistence layer and our application-specific classes using interfaces
+- We create a clean boundary between our business logic, our gateway and our application-specific classes using interfaces
- We use interfaces wherever possible, allowing concrete implementations of those interfaces to be extended without breaking the contract
- We write unit tests against interfaces, never against concrete implementations (unless interfaces don't exist)
#### ISP - The Interface Segregation Principle
@@ -155,11 +155,11 @@
## Structure
### Practical suggestions for implementation
-* The code that manages your inputs (e.g. a Rails controller) instantiates a persistence layer
+* The code that manages your inputs (e.g. a Rails controller) instantiates a gateway
object
* 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
@@ -180,11 +180,11 @@
```
input_port = CleanArchitecture::Entities::TargetedParameters.new(
use_case_actor,
TargetActiveRecordClass.find(params[:id]),
strong_params,
- persistence,
+ gateway,
other_settings_hash
)
```
* The code that manages your inputs (e.g. a Rails controller) instantiates a use case object
@@ -327,32 +327,32 @@
```ruby
module MyBusinessDomain
module UseCases
class UserUpdatesNickname < CleanArchitecture::UseCases::AbstractUseCase
contract do
- option :my_persistence_object
+ option :my_gateway_object
params do
required(:user_id).filled(:id)
required(:nickname).filled(:str)
end
rule(:nickname).validate(:not_already_taken)
register_macro(:not_already_taken) do
- unless my_persistence_object.username_is_available?(values[key_name])
+ unless my_gateway_object.username_is_available?(values[key_name])
key.failure('is already taken')
end
end
end
extend Forwardable
include Dry::Monads::Do.for(:result)
def result
valid_params = yield result_of_validating_params
- context(:my_persistence_object).result_of_updating_nickname(
+ context(:my_gateway_object).result_of_updating_nickname(
valid_params[:id],
valid_params[:nickname]
)
end
end
@@ -402,11 +402,11 @@
end
def nickname_update_form
@nickname_update_form ||= NicknameUpdateForm.new(
params: params.permit(:user_id, :nickname),
- context: { my_persistence_object: MyPersistence.new }
+ context: { my_gateway_object: MyGateway.new }
)
end
end
end
```
@@ -434,11 +434,11 @@
MyBusinessDomain::UseCases::UserUpdatesNickname.new(user_updates_nickname_parameters)
end
def user_updates_nickname_parameters
MyBusinessDomain::UseCases::UserUpdatesNickname.parameters(
- context: { my_persistence_object: MyPersistence.new },
+ context: { my_gateway_object: MyGateway.new },
user_id: params[:user_id],
nickname: params[:nickname]
)
end
end
@@ -449,22 +449,22 @@
```ruby
module MyBusinessDomain
module UseCases
class SharedContract < CleanArchitecture::UseCases::Contract
- option :my_persistence_object
+ option :my_gateway_object
register_macro(:not_already_taken?) do
unless not_already_taken?(values[key_name])
key.failure('is already taken')
end
end
private
def not_already_taken?(username)
- my_persistence_object.username_is_available?(values[key_name])
+ my_gateway_object.username_is_available?(values[key_name])
end
end
end
end
```
@@ -474,11 +474,11 @@
```ruby
module MyBusinessDomain
module UseCases
class UserUpdatesNickname < CleanArchitecture::UseCases::AbstractUseCase
contract(SharedContract) do
- option :my_persistence_object
+ option :my_gateway_object
params do
required(:user_id).filled(:id)
required(:nickname).filled(:str)
end
@@ -515,20 +515,20 @@
end
```
### `#context`
-Any context variables defined as `option`'s in your use case contract have to be specified whenever creating an instance of the parameter objects for your use case. In practice this means you can't accidentally forget to pass in say a persistence object / repository / factory / etc.
+Any context variables defined as `option`'s in your use case contract have to be specified whenever creating an instance of the parameter objects for your use case. In practice this means you can't accidentally forget to pass in say a gateway object / repository / factory / etc.
These context variables can be used within the use case using the `context` method:
```ruby
module MyBusinessDomain
module UseCases
class UserUpdatesAge < CleanArchitecture::UseCases::AbstractUseCase
contract do
- option :required_persistence_object
+ option :required_gateway_object
params do
required(:user_id).filled(:int)
required(:age).filled(:int)
end
@@ -537,11 +537,11 @@
include Dry::Monads::Do.for(:result)
def result
valid_params = yield result_of_validating_params
- context(:required_persistence_object).update_user_age_result(
+ context(:required_gateway_object).update_user_age_result(
valid_params[:user_id],
valid_params[:age]
)
end
end
@@ -558,11 +558,11 @@
```ruby
module MyBusinessDomain
module UseCases
class UserUpdatesChristmasWishlist < CleanArchitecture::UseCases::AbstractUseCase
contract do
- option :required_persistence_object
+ option :required_gateway_object
params do
required(:user_id).filled(:int)
required(:most_wanted_gift).filled(:str)
end
@@ -577,10 +577,10 @@
if Date.today == CHRISTMAS_DAY
return fail_with_error_message('Uh oh, Santa has already left the North Pole!')
end
- context(:required_persistence_object).change_most_wanted_gift(user_id, most_wanted_gift)
+ context(:required_gateway_object).change_most_wanted_gift(user_id, most_wanted_gift)
end
end
end
end
```