u-case 3.0.0.rc6 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.sh +8 -4
- data/Gemfile +9 -1
- data/README.md +160 -113
- data/README.pt-BR.md +181 -134
- data/lib/micro/case.rb +20 -15
- data/lib/micro/case/config.rb +16 -4
- data/lib/micro/case/error.rb +3 -1
- data/lib/micro/case/result.rb +54 -49
- data/lib/micro/case/result/transitions.rb +20 -0
- data/lib/micro/case/safe.rb +2 -2
- data/lib/micro/case/utils.rb +1 -0
- data/lib/micro/case/version.rb +1 -1
- data/lib/micro/case/with_activemodel_validation.rb +3 -1
- data/lib/micro/cases/flow.rb +18 -14
- data/lib/micro/cases/safe/flow.rb +1 -1
- metadata +5 -4
data/README.pt-BR.md
CHANGED
@@ -1,12 +1,29 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
[](https://travis-ci.com/serradura/u-case)
|
4
|
-
[](https://codeclimate.com/github/serradura/u-case/maintainability)
|
5
|
-
[](https://codeclimate.com/github/serradura/u-case/test_coverage)
|
1
|
+
<p align="center">
|
2
|
+
<img src="./assets/ucase_logo_v1.png" alt="u-case - Create simple and powerful use cases as Ruby objects.">
|
6
3
|
|
7
|
-
<
|
4
|
+
<p align="center"><i>Crie simples e poderosos casos de uso como objetos em Ruby.</i></p>
|
5
|
+
<br>
|
6
|
+
</p>
|
8
7
|
|
9
|
-
|
8
|
+
<p align="center">
|
9
|
+
<img src="https://img.shields.io/badge/ruby-2.2+-ruby.svg?colorA=99004d&colorB=cc0066" alt="Ruby">
|
10
|
+
|
11
|
+
<a href="https://rubygems.org/gems/u-case">
|
12
|
+
<img alt="Gem" src="https://img.shields.io/gem/v/u-case.svg?style=flat-square">
|
13
|
+
</a>
|
14
|
+
|
15
|
+
<a href="https://travis-ci.com/serradura/u-case">
|
16
|
+
<img alt="Build Status" src="https://travis-ci.com/serradura/u-case.svg?branch=main">
|
17
|
+
</a>
|
18
|
+
|
19
|
+
<a href="https://codeclimate.com/github/serradura/u-case/maintainability">
|
20
|
+
<img alt="Maintainability" src="https://api.codeclimate.com/v1/badges/5c3c8ad1b0b943f88efd/maintainability">
|
21
|
+
</a>
|
22
|
+
|
23
|
+
<a href="https://codeclimate.com/github/serradura/u-case/test_coverage">
|
24
|
+
<img alt="Test Coverage" src="https://api.codeclimate.com/v1/badges/5c3c8ad1b0b943f88efd/test_coverage">
|
25
|
+
</a>
|
26
|
+
</p>
|
10
27
|
|
11
28
|
Principais objetivos deste projeto:
|
12
29
|
1. Fácil de usar e aprender ( entrada **>>** processamento **>>** saída ).
|
@@ -15,13 +32,13 @@ Principais objetivos deste projeto:
|
|
15
32
|
4. Resolver regras de negócio complexas, ao permitir uma composição de casos de uso (criação de fluxos).
|
16
33
|
5. Ser rápido e otimizado (verifique a [seção de benchmarks](#benchmarks)).
|
17
34
|
|
18
|
-
> **Nota:** Verifique o repo https://github.com/serradura/from-fat-controllers-to-use-cases para ver uma aplicação Ruby on Rails que utiliza
|
35
|
+
> **Nota:** Verifique o repo https://github.com/serradura/from-fat-controllers-to-use-cases para ver uma aplicação Ruby on Rails que utiliza esta gem para resolver as regras de negócio.
|
19
36
|
|
20
37
|
## Documentação <!-- omit in toc -->
|
21
38
|
|
22
39
|
Versão | Documentação
|
23
40
|
--------- | -------------
|
24
|
-
3.
|
41
|
+
3.1.0 | https://github.com/serradura/u-case/blob/main/README.md
|
25
42
|
2.6.0 | https://github.com/serradura/u-case/blob/v2.x/README.md
|
26
43
|
1.1.0 | https://github.com/serradura/u-case/blob/v1.x/README.md
|
27
44
|
|
@@ -33,8 +50,8 @@ Versão | Documentação
|
|
33
50
|
- [`Micro::Case` - Como definir um caso de uso?](#microcase---como-definir-um-caso-de-uso)
|
34
51
|
- [`Micro::Case::Result` - O que é o resultado de um caso de uso?](#microcaseresult---o-que-é-o-resultado-de-um-caso-de-uso)
|
35
52
|
- [O que são os tipos de resultados?](#o-que-são-os-tipos-de-resultados)
|
36
|
-
- [Como
|
37
|
-
- [É
|
53
|
+
- [Como definir tipos customizados de resultados?](#como-definir-tipos-customizados-de-resultados)
|
54
|
+
- [É possível definir um tipo sem definir os dados do resultado?](#é-possível-definir-um-tipo-sem-definir-os-dados-do-resultado)
|
38
55
|
- [Como utilizar os hooks dos resultados?](#como-utilizar-os-hooks-dos-resultados)
|
39
56
|
- [Por que o hook sem um tipo definido expõe o próprio resultado?](#por-que-o-hook-sem-um-tipo-definido-expõe-o-próprio-resultado)
|
40
57
|
- [Usando decomposição para acessar os dados e tipo do resultado](#usando-decomposição-para-acessar-os-dados-e-tipo-do-resultado)
|
@@ -59,15 +76,15 @@ Versão | Documentação
|
|
59
76
|
- [`Kind::Validator`](#kindvalidator)
|
60
77
|
- [`Micro::Case.config`](#microcaseconfig)
|
61
78
|
- [Benchmarks](#benchmarks)
|
62
|
-
- [`Micro::Case`
|
79
|
+
- [`Micro::Case`](#microcase)
|
63
80
|
- [Success results](#success-results)
|
64
81
|
- [Failure results](#failure-results)
|
65
|
-
- [`Micro::Cases::Flow`
|
82
|
+
- [`Micro::Cases::Flow`](#microcasesflow)
|
66
83
|
- [Comparações](#comparações)
|
67
84
|
- [Exemplos](#exemplos)
|
68
|
-
- [1️⃣
|
69
|
-
- [2️⃣
|
70
|
-
- [3️⃣
|
85
|
+
- [1️⃣ Criação de usuários](#1️⃣-criação-de-usuários)
|
86
|
+
- [2️⃣ Rails App (API)](#2️⃣-rails-app-api)
|
87
|
+
- [3️⃣ CLI calculator](#3️⃣-cli-calculator)
|
71
88
|
- [4️⃣ Interceptando exceções dentro dos casos de uso](#4️⃣-interceptando-exceções-dentro-dos-casos-de-uso)
|
72
89
|
- [Desenvolvimento](#desenvolvimento)
|
73
90
|
- [Contribuindo](#contribuindo)
|
@@ -78,7 +95,7 @@ Versão | Documentação
|
|
78
95
|
|
79
96
|
| u-case | branch | ruby | activemodel |
|
80
97
|
| -------------- | ------- | -------- | ------------- |
|
81
|
-
| 3.
|
98
|
+
| 3.1.0 | main | >= 2.2.0 | >= 3.2, < 6.1 |
|
82
99
|
| 2.6.0 | v2.x | >= 2.2.0 | >= 3.2, < 6.1 |
|
83
100
|
| 1.1.0 | v1.x | >= 2.2.0 | >= 3.2, < 6.1 |
|
84
101
|
|
@@ -101,7 +118,7 @@ Versão | Documentação
|
|
101
118
|
Adicione essa linha ao Gemfile da sua aplicação:
|
102
119
|
|
103
120
|
```ruby
|
104
|
-
gem 'u-case', '~> 3.
|
121
|
+
gem 'u-case', '~> 3.1.0'
|
105
122
|
```
|
106
123
|
|
107
124
|
E então execute:
|
@@ -161,18 +178,18 @@ bad_result.data # { message: "`a` and `b` attributes must be numeric" }
|
|
161
178
|
### `Micro::Case::Result` - O que é o resultado de um caso de uso?
|
162
179
|
|
163
180
|
Um `Micro::Case::Result` armazena os dados de output de um caso de uso. Esses são seus métodos:
|
164
|
-
- `#success?` retorna true se for um resultado de sucesso.
|
165
|
-
- `#failure?` retorna true se for um resultado de falha.
|
166
|
-
- `#use_case` retorna o caso de uso
|
181
|
+
- `#success?` retorna `true` se for um resultado de sucesso.
|
182
|
+
- `#failure?` retorna `true` se for um resultado de falha.
|
183
|
+
- `#use_case` retorna o caso de uso responsável pelo resultado. Essa funcionalidade é útil para lidar com falhas em flows (esse tópico será abordado mais a frente).
|
167
184
|
- `#type` retorna um Symbol que dá significado ao resultado, isso é útil para declarar diferentes tipos de falha e sucesso.
|
168
|
-
- `#data` os dados do resultado (um Hash).
|
185
|
+
- `#data` os dados do resultado (um `Hash`).
|
169
186
|
- `#[]` e `#values_at` são atalhos para acessar as propriedades do `#data`.
|
170
187
|
- `#key?` retorna `true` se a chave estiver present no `#data`.
|
171
188
|
- `#value?` retorna `true` se o valor estiver present no `#data`.
|
172
|
-
- `#slice` retorna um novo
|
189
|
+
- `#slice` retorna um novo `Hash` que inclui apenas as chaves fornecidas. Se as chaves fornecidas não existirem, um `Hash` vazio será retornado.
|
173
190
|
- `#on_success` or `#on_failure` são métodos de hooks que te auxiliam a definir o fluxo da aplicação.
|
174
|
-
- `#then` este método permite aplicar novos casos de uso ao resultado atual se ele for sucesso. A
|
175
|
-
- `#transitions` retorna um array com
|
191
|
+
- `#then` este método permite aplicar novos casos de uso ao resultado atual se ele for sucesso. A ideia dessa feature é a criação de fluxos dinâmicos.
|
192
|
+
- `#transitions` retorna um array com todas as transformações que um resultado [teve durante um flow](#como-entender-o-que-aconteceu-durante-a-execução-de-um-flow).
|
176
193
|
|
177
194
|
> **Nota:** por conta de retrocompatibilidade, você pode usar o método `#value` como um alias para o método `#data`.
|
178
195
|
|
@@ -180,9 +197,9 @@ Um `Micro::Case::Result` armazena os dados de output de um caso de uso. Esses s
|
|
180
197
|
|
181
198
|
#### O que são os tipos de resultados?
|
182
199
|
|
183
|
-
Todo resultado tem um tipo (type), e
|
184
|
-
- `:ok`
|
185
|
-
- `:error`
|
200
|
+
Todo resultado tem um tipo (`#type`), e estes são os valores padrões:
|
201
|
+
- `:ok` em casos de sucesso;
|
202
|
+
- `:error` ou `:exception` em casos de falhas.
|
186
203
|
|
187
204
|
```ruby
|
188
205
|
class Divide < Micro::Case
|
@@ -238,9 +255,9 @@ err_result.use_case # #<Divide:0x0000 @__attributes={"a"=>2, "b"=>0}, @a=2, @b=0
|
|
238
255
|
|
239
256
|
[⬆️ Voltar para o índice](#índice-)
|
240
257
|
|
241
|
-
#### Como
|
258
|
+
#### Como definir tipos customizados de resultados?
|
242
259
|
|
243
|
-
Resposta: Use um Symbol com argumento dos métodos `Success()`, `Failure()` e declare o `result:` keyword para definir os dados do resultado.
|
260
|
+
Resposta: Use um `Symbol` com argumento dos métodos `Success()`, `Failure()` e declare o `result:` keyword para definir os dados do resultado.
|
244
261
|
|
245
262
|
```ruby
|
246
263
|
class Multiply < Micro::Case
|
@@ -276,7 +293,7 @@ bad_result.failure? # true
|
|
276
293
|
|
277
294
|
[⬆️ Voltar para o índice](#índice-)
|
278
295
|
|
279
|
-
#### É
|
296
|
+
#### É possível definir um tipo sem definir os dados do resultado?
|
280
297
|
|
281
298
|
Resposta: Sim, é possível. Mas isso terá um comportamento especial por conta dos dados do resultado ser um hash com o tipo definido como chave e `true` como o valor.
|
282
299
|
|
@@ -310,10 +327,10 @@ result.use_case.attributes # {"a"=>2, "b"=>"2"}
|
|
310
327
|
|
311
328
|
#### Como utilizar os hooks dos resultados?
|
312
329
|
|
313
|
-
Como [mencionando anteriormente](#microcaseresult---o-que-é-o-resultado-de-um-caso-de-uso), o `Micro::Case::Result` tem dois
|
330
|
+
Como [mencionando anteriormente](#microcaseresult---o-que-é-o-resultado-de-um-caso-de-uso), o `Micro::Case::Result` tem dois métodos para melhorar o controle do fluxo da aplicação. São eles:
|
314
331
|
`#on_success`, `on_failure`.
|
315
332
|
|
316
|
-
Os exemplos abaixo demonstram
|
333
|
+
Os exemplos abaixo os demonstram em uso:
|
317
334
|
|
318
335
|
```ruby
|
319
336
|
class Double < Micro::Case
|
@@ -457,7 +474,7 @@ result[:number] * 4 == accum # true
|
|
457
474
|
|
458
475
|
#### Como usar o método `Micro::Case::Result#then`?
|
459
476
|
|
460
|
-
Este método permite você criar fluxos dinâmicos
|
477
|
+
Este método permite você criar fluxos dinâmicos. Com ele, você pode adicionar novos casos de uso ou fluxos para continuar a transformação de um resultado. Exemplo:
|
461
478
|
|
462
479
|
```ruby
|
463
480
|
class ForbidNegativeNumber < Micro::Case
|
@@ -715,7 +732,7 @@ DoubleAllNumbersAndSquareAndAdd2
|
|
715
732
|
|
716
733
|
#### É possível que um fluxo acumule sua entrada e mescle cada resultado de sucesso para usar como argumento dos próximos casos de uso?
|
717
734
|
|
718
|
-
Resposta: Sim, é possível! Veja o exemplo abaixo para entender como funciona o
|
735
|
+
Resposta: Sim, é possível! Veja o exemplo abaixo para entender como funciona o acúmulo de dados dentro da execução de um fluxo.
|
719
736
|
|
720
737
|
```ruby
|
721
738
|
module Users
|
@@ -955,7 +972,7 @@ end
|
|
955
972
|
|
956
973
|
#### `Micro::Case::Result#on_exception`
|
957
974
|
|
958
|
-
Se você precisar lidar com um erro específico, recomendo o uso de uma instrução case.
|
975
|
+
Se você precisar lidar com um erro específico, recomendo o uso de uma instrução case. Exemplo:
|
959
976
|
|
960
977
|
```ruby
|
961
978
|
result.on_failure(:exception) do |data, use_case|
|
@@ -1064,7 +1081,7 @@ class Multiply < Micro::Case
|
|
1064
1081
|
validates :a, :b, presence: true, numericality: true
|
1065
1082
|
|
1066
1083
|
def call!
|
1067
|
-
return Failure :
|
1084
|
+
return Failure :invalid_attributes, result: { errors: self.errors } if invalid?
|
1068
1085
|
|
1069
1086
|
Success result: { number: a * b }
|
1070
1087
|
end
|
@@ -1174,48 +1191,48 @@ end
|
|
1174
1191
|
|
1175
1192
|
## Benchmarks
|
1176
1193
|
|
1177
|
-
### `Micro::Case`
|
1194
|
+
### `Micro::Case`
|
1178
1195
|
|
1179
1196
|
#### Success results
|
1180
1197
|
|
1181
1198
|
| Gem / Abstração | Iterações por segundo | Comparação |
|
1182
1199
|
| ----------------- | --------------------: | ----------------: |
|
1183
|
-
| Dry::Monads |
|
1184
|
-
| **Micro::Case** |
|
1185
|
-
| Interactor |
|
1186
|
-
| Trailblazer::Operation |
|
1187
|
-
| Dry::Transaction |
|
1200
|
+
| Dry::Monads | 141730.1 | _**O mais rápido**_ |
|
1201
|
+
| **Micro::Case** | 103541.3 | 1.37x slower |
|
1202
|
+
| Interactor | 29100.8 | 4.87x slower |
|
1203
|
+
| Trailblazer::Operation | 15031.4 | 9.43x slower |
|
1204
|
+
| Dry::Transaction | 5674.0 | 24.98x slower |
|
1188
1205
|
|
1189
1206
|
<details>
|
1190
1207
|
<summary>Show the full <a href="https://github.com/evanphx/benchmark-ips">benchmark/ips</a> results.</summary>
|
1191
1208
|
|
1192
1209
|
```ruby
|
1193
1210
|
# Warming up --------------------------------------
|
1194
|
-
# Interactor
|
1195
|
-
# Trailblazer::Operation 1.
|
1196
|
-
# Dry::Monads 14.
|
1197
|
-
# Dry::Transaction
|
1198
|
-
# Micro::Case 10.
|
1199
|
-
# Micro::Case::Strict 8.
|
1200
|
-
# Micro::Case::Safe 10.
|
1211
|
+
# Interactor 2.915k i/100ms
|
1212
|
+
# Trailblazer::Operation 1.543k i/100ms
|
1213
|
+
# Dry::Monads 14.288k i/100ms
|
1214
|
+
# Dry::Transaction 571.000 i/100ms
|
1215
|
+
# Micro::Case 10.418k i/100ms
|
1216
|
+
# Micro::Case::Strict 8.296k i/100ms
|
1217
|
+
# Micro::Case::Safe 10.254k i/100ms
|
1201
1218
|
|
1202
1219
|
# Calculating -------------------------------------
|
1203
|
-
# Interactor
|
1204
|
-
# Trailblazer::Operation
|
1205
|
-
# Dry::Monads
|
1206
|
-
# Dry::Transaction 5.
|
1207
|
-
# Micro::Case
|
1208
|
-
# Micro::Case::Strict
|
1209
|
-
# Micro::Case::Safe 101.
|
1220
|
+
# Interactor 29.101k (± 2.1%) i/s - 145.750k in 5.010660s
|
1221
|
+
# Trailblazer::Operation 15.031k (± 2.0%) i/s - 75.607k in 5.032071s
|
1222
|
+
# Dry::Monads 141.730k (± 3.1%) i/s - 714.400k in 5.045546s
|
1223
|
+
# Dry::Transaction 5.674k (± 1.9%) i/s - 28.550k in 5.033564s
|
1224
|
+
# Micro::Case 103.541k (± 1.6%) i/s - 520.900k in 5.032077s
|
1225
|
+
# Micro::Case::Strict 83.045k (± 2.4%) i/s - 423.096k in 5.098031s
|
1226
|
+
# Micro::Case::Safe 101.662k (± 1.5%) i/s - 512.700k in 5.044386s
|
1210
1227
|
|
1211
1228
|
# Comparison:
|
1212
|
-
# Dry::Monads:
|
1213
|
-
#
|
1214
|
-
#
|
1215
|
-
# Micro::Case::Strict:
|
1216
|
-
# Interactor:
|
1217
|
-
# Trailblazer::Operation:
|
1218
|
-
# Dry::Transaction:
|
1229
|
+
# Dry::Monads: 141730.1 i/s
|
1230
|
+
# Micro::Case: 103541.3 i/s - 1.37x (± 0.00) slower
|
1231
|
+
# Micro::Case::Safe: 101662.2 i/s - 1.39x (± 0.00) slower
|
1232
|
+
# Micro::Case::Strict: 83044.6 i/s - 1.71x (± 0.00) slower
|
1233
|
+
# Interactor: 29100.8 i/s - 4.87x (± 0.00) slower
|
1234
|
+
# Trailblazer::Operation: 15031.4 i/s - 9.43x (± 0.00) slower
|
1235
|
+
# Dry::Transaction: 5674.0 i/s - 24.98x (± 0.00) slower
|
1219
1236
|
```
|
1220
1237
|
</details>
|
1221
1238
|
|
@@ -1225,42 +1242,42 @@ https://github.com/serradura/u-case/blob/main/benchmarks/use_case/with_success_r
|
|
1225
1242
|
|
1226
1243
|
| Gem / Abstração | Iterações por segundo | Comparação |
|
1227
1244
|
| ----------------- | --------------------: | ----------------: |
|
1228
|
-
| **Micro::Case** |
|
1229
|
-
| Dry::Monads |
|
1230
|
-
| Trailblazer::Operation |
|
1231
|
-
| Interactor |
|
1232
|
-
| Dry::Transaction |
|
1245
|
+
| **Micro::Case** | 98820.8 | _**O mais rápido**_ |
|
1246
|
+
| Dry::Monads | 71329.7 | 1.39x slower |
|
1247
|
+
| Trailblazer::Operation | 15034.9 | 6.57x slower |
|
1248
|
+
| Interactor | 13958.7 | 7.08x slower |
|
1249
|
+
| Dry::Transaction | 5067.5 | 19.50x slower |
|
1233
1250
|
|
1234
1251
|
<details>
|
1235
1252
|
<summary>Mostrar o resultado completo do <a href="https://github.com/evanphx/benchmark-ips">benchmark/ips</a>.</summary>
|
1236
1253
|
|
1237
1254
|
```ruby
|
1238
1255
|
# Warming up --------------------------------------
|
1239
|
-
# Interactor 1.
|
1240
|
-
# Trailblazer::Operation 1.
|
1241
|
-
# Dry::Monads 7.
|
1242
|
-
# Dry::Transaction
|
1243
|
-
# Micro::Case 9.
|
1244
|
-
# Micro::Case::Strict 7.
|
1245
|
-
# Micro::Case::Safe 9.
|
1256
|
+
# Interactor 1.324k i/100ms
|
1257
|
+
# Trailblazer::Operation 1.525k i/100ms
|
1258
|
+
# Dry::Monads 7.126k i/100ms
|
1259
|
+
# Dry::Transaction 499.000 i/100ms
|
1260
|
+
# Micro::Case 9.919k i/100ms
|
1261
|
+
# Micro::Case::Strict 7.837k i/100ms
|
1262
|
+
# Micro::Case::Safe 9.762k i/100ms
|
1246
1263
|
|
1247
1264
|
# Calculating -------------------------------------
|
1248
|
-
# Interactor 13.
|
1249
|
-
# Trailblazer::Operation
|
1250
|
-
# Dry::Monads
|
1251
|
-
# Dry::Transaction
|
1252
|
-
# Micro::Case
|
1253
|
-
# Micro::Case::Strict
|
1254
|
-
# Micro::Case::Safe
|
1265
|
+
# Interactor 13.959k (± 2.5%) i/s - 70.172k in 5.030240s
|
1266
|
+
# Trailblazer::Operation 15.035k (± 2.2%) i/s - 76.250k in 5.074108s
|
1267
|
+
# Dry::Monads 71.330k (± 2.4%) i/s - 363.426k in 5.097993s
|
1268
|
+
# Dry::Transaction 5.068k (± 1.9%) i/s - 25.449k in 5.023922s
|
1269
|
+
# Micro::Case 98.821k (± 2.9%) i/s - 495.950k in 5.023421s
|
1270
|
+
# Micro::Case::Strict 79.936k (± 3.1%) i/s - 399.687k in 5.005435s
|
1271
|
+
# Micro::Case::Safe 98.695k (± 1.9%) i/s - 497.862k in 5.046246s
|
1255
1272
|
|
1256
1273
|
# Comparison:
|
1257
|
-
# Micro::Case:
|
1258
|
-
# Micro::Case::Safe:
|
1259
|
-
# Micro::Case::Strict:
|
1260
|
-
# Dry::Monads:
|
1261
|
-
# Trailblazer::Operation:
|
1262
|
-
# Interactor:
|
1263
|
-
# Dry::Transaction:
|
1274
|
+
# Micro::Case: 98820.8 i/s
|
1275
|
+
# Micro::Case::Safe: 98695.0 i/s - same-ish: difference falls within error
|
1276
|
+
# Micro::Case::Strict: 79935.9 i/s - 1.24x (± 0.00) slower
|
1277
|
+
# Dry::Monads: 71329.7 i/s - 1.39x (± 0.00) slower
|
1278
|
+
# Trailblazer::Operation: 15034.9 i/s - 6.57x (± 0.00) slower
|
1279
|
+
# Interactor: 13958.7 i/s - 7.08x (± 0.00) slower
|
1280
|
+
# Dry::Transaction: 5067.5 i/s - 19.50x (± 0.00) slower
|
1264
1281
|
```
|
1265
1282
|
</details>
|
1266
1283
|
|
@@ -1268,15 +1285,16 @@ https://github.com/serradura/u-case/blob/main/benchmarks/use_case/with_failure_r
|
|
1268
1285
|
|
1269
1286
|
---
|
1270
1287
|
|
1271
|
-
### `Micro::Cases::Flow`
|
1288
|
+
### `Micro::Cases::Flow`
|
1272
1289
|
|
1273
1290
|
| Gem / Abstração | [Resultados de sucesso](https://github.com/serradura/u-case/blob/main/benchmarks/flow/with_success_result.rb#L40) | [Resultados de falha](https://github.com/serradura/u-case/blob/main/benchmarks/flow/with_failure_result.rb#L40) |
|
1274
1291
|
| ------------------------------------------- | ----------------: | ----------------: |
|
1275
1292
|
| Micro::Case internal flow (private methods) | _**O mais rápido**_ | _**O mais rápido**_ |
|
1276
|
-
| Micro::Case
|
1277
|
-
| Micro::
|
1278
|
-
| Micro::Cases.
|
1279
|
-
|
|
1293
|
+
| Micro::Case internal flow (through lambdas) | 1.03x slower | 1.04x slower |
|
1294
|
+
| Micro::Case `then` method | 1.49x slower | 0x slower |
|
1295
|
+
| Micro::Cases.flow | 1.53x slower | 1.04x slower |
|
1296
|
+
| Micro::Cases.safe_flow | 1.54x slower | 1.04x slower |
|
1297
|
+
| Interactor::Organizer | 2.05x slower | 6.27x slower |
|
1280
1298
|
|
1281
1299
|
\* As gems `Dry::Monads`, `Dry::Transaction`, `Trailblazer::Operation` estão fora desta análise por não terem esse tipo de funcionalidade.
|
1282
1300
|
|
@@ -1285,25 +1303,40 @@ https://github.com/serradura/u-case/blob/main/benchmarks/use_case/with_failure_r
|
|
1285
1303
|
|
1286
1304
|
```ruby
|
1287
1305
|
# Warming up --------------------------------------
|
1288
|
-
# Interactor::Organizer
|
1289
|
-
#
|
1290
|
-
# Micro::Cases
|
1291
|
-
#
|
1292
|
-
# Micro::
|
1306
|
+
# Interactor::Organizer
|
1307
|
+
# 4.837k i/100ms
|
1308
|
+
# Micro::Cases.flow([])
|
1309
|
+
# 6.755k i/100ms
|
1310
|
+
# Micro::Cases::safe_flow([])
|
1311
|
+
# 6.809k i/100ms
|
1312
|
+
# Micro::Case flow using `then` method
|
1313
|
+
# 6.968k i/100ms
|
1314
|
+
# Micro::Case flow using private methods
|
1315
|
+
# 10.362k i/100ms
|
1316
|
+
# Micro::Case flow using private methods through lambdas
|
1317
|
+
# 10.258k i/100ms
|
1293
1318
|
|
1294
1319
|
# Calculating -------------------------------------
|
1295
|
-
# Interactor::Organizer
|
1296
|
-
#
|
1297
|
-
# Micro::Cases
|
1298
|
-
#
|
1299
|
-
# Micro::
|
1320
|
+
# Interactor::Organizer
|
1321
|
+
# 50.731k (± 1.6%) i/s - 256.361k in 5.054694s
|
1322
|
+
# Micro::Cases.flow([])
|
1323
|
+
# 67.757k (± 1.6%) i/s - 344.505k in 5.085681s
|
1324
|
+
# Micro::Cases::safe_flow([])
|
1325
|
+
# 67.613k (± 1.6%) i/s - 340.450k in 5.036562s
|
1326
|
+
# Micro::Case flow using `then` method
|
1327
|
+
# 69.483k (± 1.5%) i/s - 348.400k in 5.015351s
|
1328
|
+
# Micro::Case flow using private methods
|
1329
|
+
# 103.788k (± 1.0%) i/s - 528.462k in 5.092240s
|
1330
|
+
# Micro::Case flow using private methods through lambdas
|
1331
|
+
# 101.081k (± 1.2%) i/s - 512.900k in 5.074904s
|
1300
1332
|
|
1301
1333
|
# Comparison:
|
1302
|
-
# Micro::Case flow using private methods:
|
1303
|
-
# Micro::Case flow using
|
1304
|
-
# Micro::
|
1305
|
-
# Micro::Cases
|
1306
|
-
#
|
1334
|
+
# Micro::Case flow using private methods: 103787.5 i/s
|
1335
|
+
# Micro::Case flow using private methods through lambdas: 101080.6 i/s - 1.03x (± 0.00) slower
|
1336
|
+
# Micro::Case flow using `then` method: 69483.3 i/s - 1.49x (± 0.00) slower
|
1337
|
+
# Micro::Cases.flow([]): 67757.2 i/s - 1.53x (± 0.00) slower
|
1338
|
+
# Micro::Cases::safe_flow([]): 67613.3 i/s - 1.54x (± 0.00) slower
|
1339
|
+
# Interactor::Organizer: 50730.8 i/s - 2.05x (± 0.00) slower
|
1307
1340
|
```
|
1308
1341
|
</details>
|
1309
1342
|
|
@@ -1312,25 +1345,39 @@ https://github.com/serradura/u-case/blob/main/benchmarks/use_case/with_failure_r
|
|
1312
1345
|
|
1313
1346
|
```ruby
|
1314
1347
|
# Warming up --------------------------------------
|
1315
|
-
# Interactor::Organizer
|
1316
|
-
#
|
1317
|
-
# Micro::Cases
|
1318
|
-
#
|
1319
|
-
# Micro::
|
1320
|
-
|
1348
|
+
# Interactor::Organizer
|
1349
|
+
# 2.299k i/100ms
|
1350
|
+
# Micro::Cases.flow([])
|
1351
|
+
# 14.187k i/100ms
|
1352
|
+
# Micro::Cases::safe_flow([])
|
1353
|
+
# 13.609k i/100ms
|
1354
|
+
# Micro::Case flow using `then` method
|
1355
|
+
# 14.578k i/100ms
|
1356
|
+
# Micro::Case flow using private methods
|
1357
|
+
# 14.101k i/100ms
|
1358
|
+
# Micro::Case flow using private methods through lambdas
|
1359
|
+
# 13.670k i/100ms
|
1321
1360
|
# Calculating -------------------------------------
|
1322
|
-
# Interactor::Organizer
|
1323
|
-
#
|
1324
|
-
# Micro::Cases
|
1325
|
-
#
|
1326
|
-
# Micro::
|
1361
|
+
# Interactor::Organizer
|
1362
|
+
# 23.306k (± 2.1%) i/s - 117.249k in 5.033171s
|
1363
|
+
# Micro::Cases.flow([])
|
1364
|
+
# 140.111k (± 1.6%) i/s - 709.350k in 5.064041s
|
1365
|
+
# Micro::Cases::safe_flow([])
|
1366
|
+
# 139.927k (± 1.7%) i/s - 707.668k in 5.058971s
|
1367
|
+
# Micro::Case flow using `then` method
|
1368
|
+
# 146.073k (± 2.0%) i/s - 743.478k in 5.091741s
|
1369
|
+
# Micro::Case flow using private methods
|
1370
|
+
# 142.092k (± 1.5%) i/s - 719.151k in 5.062298s
|
1371
|
+
# Micro::Case flow using private methods through lambdas
|
1372
|
+
# 140.791k (± 1.2%) i/s - 710.840k in 5.049584s
|
1327
1373
|
|
1328
1374
|
# Comparison:
|
1329
|
-
# Micro::Case flow using `then` method:
|
1330
|
-
# Micro::Case flow using private methods:
|
1331
|
-
# Micro::
|
1332
|
-
# Micro::Cases.flow([]):
|
1333
|
-
#
|
1375
|
+
# Micro::Case flow using `then` method: 146073.0 i/s
|
1376
|
+
# Micro::Case flow using private methods: 142091.7 i/s - same-ish: difference falls within error
|
1377
|
+
# Micro::Case flow using private methods through lambdas: 140791.1 i/s - 1.04x (± 0.00) slower
|
1378
|
+
# Micro::Cases.flow([]): 140110.8 i/s - 1.04x (± 0.00) slower
|
1379
|
+
# Micro::Cases::safe_flow([]): 139926.6 i/s - 1.04x (± 0.00) slower
|
1380
|
+
# Interactor::Organizer: 23305.9 i/s - 6.27x (± 0.00) slower
|
1334
1381
|
```
|
1335
1382
|
</details>
|
1336
1383
|
|
@@ -1347,24 +1394,24 @@ Confira as implementações do mesmo caso de uso com diferentes gems/abstraçõe
|
|
1347
1394
|
|
1348
1395
|
## Exemplos
|
1349
1396
|
|
1350
|
-
### 1️⃣
|
1397
|
+
### 1️⃣ Criação de usuários
|
1398
|
+
|
1399
|
+
> Um exemplo de fluxo que define etapas para higienizar, validar e persistir seus dados de entrada. Ele tem todas as abordagens possíveis para representar casos de uso com a gem `u-case`.
|
1400
|
+
>
|
1401
|
+
> Link: https://github.com/serradura/u-case/blob/main/examples/users_creation
|
1402
|
+
|
1403
|
+
### 2️⃣ Rails App (API)
|
1351
1404
|
|
1352
1405
|
> Este projeto mostra diferentes tipos de arquitetura (uma por commit), e na última, como usar a gem `Micro::Case` para lidar com a lógica de negócios da aplicação.
|
1353
1406
|
>
|
1354
1407
|
> Link: https://github.com/serradura/from-fat-controllers-to-use-cases
|
1355
1408
|
|
1356
|
-
###
|
1409
|
+
### 3️⃣ CLI calculator
|
1357
1410
|
|
1358
1411
|
> Rake tasks para demonstrar como lidar com os dados do usuário e como usar diferentes tipos de falha para controlar o fluxo do programa.
|
1359
1412
|
>
|
1360
1413
|
> Link: https://github.com/serradura/u-case/tree/main/examples/calculator
|
1361
1414
|
|
1362
|
-
### 3️⃣ Criação de usuários
|
1363
|
-
|
1364
|
-
> Um exemplo de fluxo de caso de uso que define etapas para higienizar, validar e persistir seus dados de entrada.
|
1365
|
-
>
|
1366
|
-
> Link: https://github.com/serradura/u-case/blob/main/examples/users_creation.rb
|
1367
|
-
|
1368
1415
|
### 4️⃣ Interceptando exceções dentro dos casos de uso
|
1369
1416
|
|
1370
1417
|
> Link: https://github.com/serradura/u-case/blob/main/examples/rescuing_exceptions.rb
|