u-case 3.0.0.rc7 → 4.0.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 +191 -122
- data/README.pt-BR.md +212 -143
- data/lib/micro/case.rb +23 -17
- data/lib/micro/case/config.rb +16 -4
- data/lib/micro/case/error.rb +7 -2
- data/lib/micro/case/result.rb +58 -47
- data/lib/micro/case/result/transitions.rb +18 -0
- data/lib/micro/case/safe.rb +2 -2
- data/lib/micro/case/strict.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
- data/u-case.gemspec +3 -3
- metadata +11 -8
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 - Represent use cases in a simple and powerful way while writing modular, expressive and sequentially logical code.">
|
6
3
|
|
7
|
-
<
|
4
|
+
<p align="center"><i> Represente casos de uso de forma simples e poderosa ao escrever código modular, expressivo e sequencialmente lógico.</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,14 @@ 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
|
-
|
41
|
+
4.0.0 | https://github.com/serradura/u-case/blob/main/README.md
|
42
|
+
3.1.0 | https://github.com/serradura/u-case/blob/v3.x/README.md
|
25
43
|
2.6.0 | https://github.com/serradura/u-case/blob/v2.x/README.md
|
26
44
|
1.1.0 | https://github.com/serradura/u-case/blob/v1.x/README.md
|
27
45
|
|
@@ -33,8 +51,8 @@ Versão | Documentação
|
|
33
51
|
- [`Micro::Case` - Como definir um caso de uso?](#microcase---como-definir-um-caso-de-uso)
|
34
52
|
- [`Micro::Case::Result` - O que é o resultado de um caso de uso?](#microcaseresult---o-que-é-o-resultado-de-um-caso-de-uso)
|
35
53
|
- [O que são os tipos de resultados?](#o-que-são-os-tipos-de-resultados)
|
36
|
-
- [Como
|
37
|
-
- [É
|
54
|
+
- [Como definir tipos customizados de resultados?](#como-definir-tipos-customizados-de-resultados)
|
55
|
+
- [É possível definir um tipo sem definir os dados do resultado?](#é-possível-definir-um-tipo-sem-definir-os-dados-do-resultado)
|
38
56
|
- [Como utilizar os hooks dos resultados?](#como-utilizar-os-hooks-dos-resultados)
|
39
57
|
- [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
58
|
- [Usando decomposição para acessar os dados e tipo do resultado](#usando-decomposição-para-acessar-os-dados-e-tipo-do-resultado)
|
@@ -59,15 +77,18 @@ Versão | Documentação
|
|
59
77
|
- [`Kind::Validator`](#kindvalidator)
|
60
78
|
- [`Micro::Case.config`](#microcaseconfig)
|
61
79
|
- [Benchmarks](#benchmarks)
|
62
|
-
- [`Micro::Case`
|
80
|
+
- [`Micro::Case`](#microcase)
|
63
81
|
- [Success results](#success-results)
|
64
82
|
- [Failure results](#failure-results)
|
65
|
-
- [`Micro::Cases::Flow`
|
83
|
+
- [`Micro::Cases::Flow`](#microcasesflow)
|
84
|
+
- [Execuntando os benchmarks](#execuntando-os-benchmarks)
|
85
|
+
- [Performance (Benchmarks IPS)](#performance-benchmarks-ips)
|
86
|
+
- [Memory profiling](#memory-profiling)
|
66
87
|
- [Comparações](#comparações)
|
67
88
|
- [Exemplos](#exemplos)
|
68
|
-
- [1️⃣
|
69
|
-
- [2️⃣
|
70
|
-
- [3️⃣
|
89
|
+
- [1️⃣ Criação de usuários](#1️⃣-criação-de-usuários)
|
90
|
+
- [2️⃣ Rails App (API)](#2️⃣-rails-app-api)
|
91
|
+
- [3️⃣ CLI calculator](#3️⃣-cli-calculator)
|
71
92
|
- [4️⃣ Interceptando exceções dentro dos casos de uso](#4️⃣-interceptando-exceções-dentro-dos-casos-de-uso)
|
72
93
|
- [Desenvolvimento](#desenvolvimento)
|
73
94
|
- [Contribuindo](#contribuindo)
|
@@ -76,11 +97,12 @@ Versão | Documentação
|
|
76
97
|
|
77
98
|
## Compatibilidade
|
78
99
|
|
79
|
-
| u-case | branch | ruby | activemodel |
|
80
|
-
| -------------- | ------- | -------- | ------------- |
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
100
|
+
| u-case | branch | ruby | activemodel | u-attributes |
|
101
|
+
| -------------- | ------- | -------- | ------------- | ------------ |
|
102
|
+
| 4.0.0 | main | >= 2.2.0 | >= 3.2, < 6.1 | ~> 2.0 |
|
103
|
+
| 3.1.0 | v3.x | >= 2.2.0 | >= 3.2, < 6.1 | ~> 1.1 |
|
104
|
+
| 2.6.0 | v2.x | >= 2.2.0 | >= 3.2, < 6.1 | ~> 1.1 |
|
105
|
+
| 1.1.0 | v1.x | >= 2.2.0 | >= 3.2, < 6.1 | ~> 1.1 |
|
84
106
|
|
85
107
|
> Nota: O activemodel é uma dependência opcional, esse módulo que [pode ser habilitado](#u-casewith_activemodel_validation---como-validar-os-atributos-do-caso-de-uso) para validar os atributos dos casos de uso.
|
86
108
|
|
@@ -101,7 +123,7 @@ Versão | Documentação
|
|
101
123
|
Adicione essa linha ao Gemfile da sua aplicação:
|
102
124
|
|
103
125
|
```ruby
|
104
|
-
gem 'u-case', '~> 3.
|
126
|
+
gem 'u-case', '~> 3.1.0'
|
105
127
|
```
|
106
128
|
|
107
129
|
E então execute:
|
@@ -110,7 +132,7 @@ E então execute:
|
|
110
132
|
|
111
133
|
Ou instale manualmente:
|
112
134
|
|
113
|
-
$ gem install u-case
|
135
|
+
$ gem install u-case
|
114
136
|
|
115
137
|
## Uso
|
116
138
|
|
@@ -161,18 +183,18 @@ bad_result.data # { message: "`a` and `b` attributes must be numeric" }
|
|
161
183
|
### `Micro::Case::Result` - O que é o resultado de um caso de uso?
|
162
184
|
|
163
185
|
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
|
186
|
+
- `#success?` retorna `true` se for um resultado de sucesso.
|
187
|
+
- `#failure?` retorna `true` se for um resultado de falha.
|
188
|
+
- `#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
189
|
- `#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).
|
190
|
+
- `#data` os dados do resultado (um `Hash`).
|
169
191
|
- `#[]` e `#values_at` são atalhos para acessar as propriedades do `#data`.
|
170
192
|
- `#key?` retorna `true` se a chave estiver present no `#data`.
|
171
193
|
- `#value?` retorna `true` se o valor estiver present no `#data`.
|
172
|
-
- `#slice` retorna um novo
|
194
|
+
- `#slice` retorna um novo `Hash` que inclui apenas as chaves fornecidas. Se as chaves fornecidas não existirem, um `Hash` vazio será retornado.
|
173
195
|
- `#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
|
196
|
+
- `#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.
|
197
|
+
- `#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
198
|
|
177
199
|
> **Nota:** por conta de retrocompatibilidade, você pode usar o método `#value` como um alias para o método `#data`.
|
178
200
|
|
@@ -180,9 +202,9 @@ Um `Micro::Case::Result` armazena os dados de output de um caso de uso. Esses s
|
|
180
202
|
|
181
203
|
#### O que são os tipos de resultados?
|
182
204
|
|
183
|
-
Todo resultado tem um tipo (type), e
|
184
|
-
- `:ok`
|
185
|
-
- `:error`
|
205
|
+
Todo resultado tem um tipo (`#type`), e estes são os valores padrões:
|
206
|
+
- `:ok` em casos de sucesso;
|
207
|
+
- `:error` ou `:exception` em casos de falhas.
|
186
208
|
|
187
209
|
```ruby
|
188
210
|
class Divide < Micro::Case
|
@@ -238,9 +260,9 @@ err_result.use_case # #<Divide:0x0000 @__attributes={"a"=>2, "b"=>0}, @a=2, @b=0
|
|
238
260
|
|
239
261
|
[⬆️ Voltar para o índice](#índice-)
|
240
262
|
|
241
|
-
#### Como
|
263
|
+
#### Como definir tipos customizados de resultados?
|
242
264
|
|
243
|
-
Resposta: Use um Symbol com argumento dos métodos `Success()`, `Failure()` e declare o `result:` keyword para definir os dados do resultado.
|
265
|
+
Resposta: Use um `Symbol` com argumento dos métodos `Success()`, `Failure()` e declare o `result:` keyword para definir os dados do resultado.
|
244
266
|
|
245
267
|
```ruby
|
246
268
|
class Multiply < Micro::Case
|
@@ -276,7 +298,7 @@ bad_result.failure? # true
|
|
276
298
|
|
277
299
|
[⬆️ Voltar para o índice](#índice-)
|
278
300
|
|
279
|
-
#### É
|
301
|
+
#### É possível definir um tipo sem definir os dados do resultado?
|
280
302
|
|
281
303
|
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
304
|
|
@@ -310,10 +332,10 @@ result.use_case.attributes # {"a"=>2, "b"=>"2"}
|
|
310
332
|
|
311
333
|
#### Como utilizar os hooks dos resultados?
|
312
334
|
|
313
|
-
Como [mencionando anteriormente](#microcaseresult---o-que-é-o-resultado-de-um-caso-de-uso), o `Micro::Case::Result` tem dois
|
335
|
+
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
336
|
`#on_success`, `on_failure`.
|
315
337
|
|
316
|
-
Os exemplos abaixo demonstram
|
338
|
+
Os exemplos abaixo os demonstram em uso:
|
317
339
|
|
318
340
|
```ruby
|
319
341
|
class Double < Micro::Case
|
@@ -457,7 +479,7 @@ result[:number] * 4 == accum # true
|
|
457
479
|
|
458
480
|
#### Como usar o método `Micro::Case::Result#then`?
|
459
481
|
|
460
|
-
Este método permite você criar fluxos dinâmicos
|
482
|
+
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
483
|
|
462
484
|
```ruby
|
463
485
|
class ForbidNegativeNumber < Micro::Case
|
@@ -715,7 +737,7 @@ DoubleAllNumbersAndSquareAndAdd2
|
|
715
737
|
|
716
738
|
#### É 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
739
|
|
718
|
-
Resposta: Sim, é possível! Veja o exemplo abaixo para entender como funciona o
|
740
|
+
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
741
|
|
720
742
|
```ruby
|
721
743
|
module Users
|
@@ -955,7 +977,7 @@ end
|
|
955
977
|
|
956
978
|
#### `Micro::Case::Result#on_exception`
|
957
979
|
|
958
|
-
Se você precisar lidar com um erro específico, recomendo o uso de uma instrução case.
|
980
|
+
Se você precisar lidar com um erro específico, recomendo o uso de uma instrução case. Exemplo:
|
959
981
|
|
960
982
|
```ruby
|
961
983
|
result.on_failure(:exception) do |data, use_case|
|
@@ -1064,7 +1086,7 @@ class Multiply < Micro::Case
|
|
1064
1086
|
validates :a, :b, presence: true, numericality: true
|
1065
1087
|
|
1066
1088
|
def call!
|
1067
|
-
return Failure :
|
1089
|
+
return Failure :invalid_attributes, result: { errors: self.errors } if invalid?
|
1068
1090
|
|
1069
1091
|
Success result: { number: a * b }
|
1070
1092
|
end
|
@@ -1174,109 +1196,110 @@ end
|
|
1174
1196
|
|
1175
1197
|
## Benchmarks
|
1176
1198
|
|
1177
|
-
### `Micro::Case`
|
1199
|
+
### `Micro::Case`
|
1178
1200
|
|
1179
1201
|
#### Success results
|
1180
1202
|
|
1181
1203
|
| Gem / Abstração | Iterações por segundo | Comparação |
|
1182
1204
|
| ----------------- | --------------------: | ----------------: |
|
1183
|
-
| Dry::Monads |
|
1184
|
-
| **Micro::Case** |
|
1185
|
-
| Interactor |
|
1186
|
-
| Trailblazer::Operation |
|
1187
|
-
| Dry::Transaction |
|
1205
|
+
| Dry::Monads | 281515.4 | _**O mais rápido**_ |
|
1206
|
+
| **Micro::Case** | 151711.3 | 1.86x mais lento |
|
1207
|
+
| Interactor | 53016.2 | 5.31x mais lento |
|
1208
|
+
| Trailblazer::Operation | 38314.2 | 7.35x mais lento |
|
1209
|
+
| Dry::Transaction | 10440.7 | 26.96x mais lento |
|
1188
1210
|
|
1189
1211
|
<details>
|
1190
1212
|
<summary>Show the full <a href="https://github.com/evanphx/benchmark-ips">benchmark/ips</a> results.</summary>
|
1191
1213
|
|
1192
1214
|
```ruby
|
1193
1215
|
# Warming up --------------------------------------
|
1194
|
-
# Interactor
|
1195
|
-
# Trailblazer::Operation
|
1196
|
-
# Dry::Monads
|
1197
|
-
# Dry::Transaction
|
1198
|
-
# Micro::Case
|
1199
|
-
#
|
1200
|
-
#
|
1216
|
+
# Interactor 5.151k i/100ms
|
1217
|
+
# Trailblazer::Operation 3.805k i/100ms
|
1218
|
+
# Dry::Monads 28.153k i/100ms
|
1219
|
+
# Dry::Transaction 1.063k i/100ms
|
1220
|
+
# Micro::Case 15.159k i/100ms
|
1221
|
+
# Micro::Case::Safe 15.172k i/100ms
|
1222
|
+
# Micro::Case::Strict 12.557k i/100ms
|
1201
1223
|
|
1202
1224
|
# Calculating -------------------------------------
|
1203
|
-
# Interactor
|
1204
|
-
# Trailblazer::Operation
|
1205
|
-
# Dry::Monads
|
1206
|
-
# Dry::Transaction
|
1207
|
-
# Micro::Case
|
1208
|
-
#
|
1209
|
-
#
|
1225
|
+
# Interactor 53.016k (± 1.8%) i/s - 267.852k in 5.053967s
|
1226
|
+
# Trailblazer::Operation 38.314k (± 1.7%) i/s - 194.055k in 5.066374s
|
1227
|
+
# Dry::Monads 281.515k (± 2.4%) i/s - 1.408M in 5.003266s
|
1228
|
+
# Dry::Transaction 10.441k (± 2.1%) i/s - 53.150k in 5.092957s
|
1229
|
+
# Micro::Case 151.711k (± 1.7%) i/s - 773.109k in 5.097555s
|
1230
|
+
# Micro::Case::Safe 145.801k (± 6.7%) i/s - 728.256k in 5.022666s
|
1231
|
+
# Micro::Case::Strict 115.636k (± 8.4%) i/s - 577.622k in 5.042079s
|
1210
1232
|
|
1211
1233
|
# Comparison:
|
1212
|
-
# Dry::Monads:
|
1213
|
-
#
|
1214
|
-
#
|
1215
|
-
# Micro::Case::Strict:
|
1216
|
-
# Interactor:
|
1217
|
-
# Trailblazer::Operation:
|
1218
|
-
# Dry::Transaction:
|
1234
|
+
# Dry::Monads: 281515.4 i/s
|
1235
|
+
# Micro::Case: 151711.3 i/s - 1.86x (± 0.00) slower
|
1236
|
+
# Micro::Case::Safe: 145800.8 i/s - 1.93x (± 0.00) slower
|
1237
|
+
# Micro::Case::Strict: 115635.8 i/s - 2.43x (± 0.00) slower
|
1238
|
+
# Interactor: 53016.2 i/s - 5.31x (± 0.00) slower
|
1239
|
+
# Trailblazer::Operation: 38314.2 i/s - 7.35x (± 0.00) slower
|
1240
|
+
# Dry::Transaction: 10440.7 i/s - 26.96x (± 0.00) slower
|
1219
1241
|
```
|
1220
1242
|
</details>
|
1221
1243
|
|
1222
|
-
https://github.com/serradura/u-case/blob/main/benchmarks/use_case/
|
1244
|
+
https://github.com/serradura/u-case/blob/main/benchmarks/perfomance/use_case/success_results.
|
1223
1245
|
|
1224
1246
|
#### Failure results
|
1225
1247
|
|
1226
1248
|
| Gem / Abstração | Iterações por segundo | Comparação |
|
1227
1249
|
| ----------------- | --------------------: | ----------------: |
|
1228
|
-
| **Micro::Case** |
|
1229
|
-
| Dry::Monads |
|
1230
|
-
| Trailblazer::Operation |
|
1231
|
-
| Interactor |
|
1232
|
-
| Dry::Transaction |
|
1250
|
+
| **Micro::Case** | 140794.0 | _**O mais rápido**_ |
|
1251
|
+
| Dry::Monads | 133865.5 | 0x mais devagar |
|
1252
|
+
| Trailblazer::Operation | 39829.9 | 3.53x mais devagar |
|
1253
|
+
| Interactor | 23856.0 | 5.90x mais devagar |
|
1254
|
+
| Dry::Transaction | 7975.0 | 17.65x mais devagar |
|
1233
1255
|
|
1234
1256
|
<details>
|
1235
1257
|
<summary>Mostrar o resultado completo do <a href="https://github.com/evanphx/benchmark-ips">benchmark/ips</a>.</summary>
|
1236
1258
|
|
1237
1259
|
```ruby
|
1238
1260
|
# Warming up --------------------------------------
|
1239
|
-
# Interactor
|
1240
|
-
# Trailblazer::Operation
|
1241
|
-
# Dry::Monads
|
1242
|
-
# Dry::Transaction
|
1243
|
-
# Micro::Case
|
1244
|
-
#
|
1245
|
-
#
|
1261
|
+
# Interactor 2.351k i/100ms
|
1262
|
+
# Trailblazer::Operation 3.941k i/100ms
|
1263
|
+
# Dry::Monads 13.567k i/100ms
|
1264
|
+
# Dry::Transaction 927.000 i/100ms
|
1265
|
+
# Micro::Case 14.959k i/100ms
|
1266
|
+
# Micro::Case::Safe 14.904k i/100ms
|
1267
|
+
# Micro::Case::Strict 12.007k i/100ms
|
1246
1268
|
|
1247
1269
|
# Calculating -------------------------------------
|
1248
|
-
# Interactor
|
1249
|
-
# Trailblazer::Operation
|
1250
|
-
# Dry::Monads
|
1251
|
-
# Dry::Transaction
|
1252
|
-
# Micro::Case
|
1253
|
-
#
|
1254
|
-
#
|
1270
|
+
# Interactor 23.856k (± 1.7%) i/s - 119.901k in 5.027585s
|
1271
|
+
# Trailblazer::Operation 39.830k (± 1.2%) i/s - 200.991k in 5.047032s
|
1272
|
+
# Dry::Monads 133.866k (± 2.5%) i/s - 678.350k in 5.070899s
|
1273
|
+
# Dry::Transaction 7.975k (± 8.6%) i/s - 39.861k in 5.036260s
|
1274
|
+
# Micro::Case 130.534k (±24.4%) i/s - 583.401k in 5.040907s
|
1275
|
+
# Micro::Case::Safe 140.794k (± 8.1%) i/s - 700.488k in 5.020935s
|
1276
|
+
# Micro::Case::Strict 102.641k (±21.3%) i/s - 480.280k in 5.020354s
|
1255
1277
|
|
1256
1278
|
# Comparison:
|
1257
|
-
#
|
1258
|
-
#
|
1259
|
-
#
|
1260
|
-
#
|
1261
|
-
# Trailblazer::Operation:
|
1262
|
-
# Interactor:
|
1263
|
-
# Dry::Transaction:
|
1279
|
+
# Micro::Case::Safe: 140794.0 i/s
|
1280
|
+
# Dry::Monads: 133865.5 i/s - same-ish: difference falls within error
|
1281
|
+
# Micro::Case: 130534.0 i/s - same-ish: difference falls within error
|
1282
|
+
# Micro::Case::Strict: 102640.7 i/s - 1.37x (± 0.00) slower
|
1283
|
+
# Trailblazer::Operation: 39829.9 i/s - 3.53x (± 0.00) slower
|
1284
|
+
# Interactor: 23856.0 i/s - 5.90x (± 0.00) slower
|
1285
|
+
# Dry::Transaction: 7975.0 i/s - 17.65x (± 0.00) slower
|
1264
1286
|
```
|
1265
1287
|
</details>
|
1266
1288
|
|
1267
|
-
https://github.com/serradura/u-case/blob/main/benchmarks/use_case/
|
1289
|
+
https://github.com/serradura/u-case/blob/main/benchmarks/perfomance/use_case/failure_results.
|
1268
1290
|
|
1269
1291
|
---
|
1270
1292
|
|
1271
|
-
### `Micro::Cases::Flow`
|
1293
|
+
### `Micro::Cases::Flow`
|
1272
1294
|
|
1273
|
-
| Gem / Abstração | [Resultados de sucesso](https://github.com/serradura/u-case/blob/main/benchmarks/flow/
|
1295
|
+
| Gem / Abstração | [Resultados de sucesso](https://github.com/serradura/u-case/blob/main/benchmarks/perfomance/flow/success_results.rb) | [Resultados de falha](https://github.com/serradura/u-case/blob/main/benchmarks/perfomance/flow/failure_results.rb) |
|
1274
1296
|
| ------------------------------------------- | ----------------: | ----------------: |
|
1275
|
-
| Micro::Case
|
1276
|
-
| Micro::Case `then` method
|
1277
|
-
| Micro::Cases.flow |
|
1278
|
-
| Micro::
|
1279
|
-
|
|
1297
|
+
| Micro::Case::Result `pipe` method | 172734.4 i/s | 153745.6 i/s |
|
1298
|
+
| Micro::Case::Result `then` method | 1.24x mais devagar | 1.21x mais devagar |
|
1299
|
+
| Micro::Cases.flow | 1.30x mais devagar | 1.30x mais devagar |
|
1300
|
+
| Micro::Case class with an inner flow | 2.05x mais devagar | 1.98x mais devagar |
|
1301
|
+
| Micro::Case class including itself as a step| 2.14x mais devagar | 2.09x mais devagar |
|
1302
|
+
| Interactor::Organizer | 7.69x mais devagar | 7.03x mais devagar |
|
1280
1303
|
|
1281
1304
|
\* As gems `Dry::Monads`, `Dry::Transaction`, `Trailblazer::Operation` estão fora desta análise por não terem esse tipo de funcionalidade.
|
1282
1305
|
|
@@ -1285,25 +1308,28 @@ https://github.com/serradura/u-case/blob/main/benchmarks/use_case/with_failure_r
|
|
1285
1308
|
|
1286
1309
|
```ruby
|
1287
1310
|
# Warming up --------------------------------------
|
1288
|
-
# Interactor::Organizer
|
1289
|
-
# Micro::Cases.flow([])
|
1290
|
-
# Micro::
|
1291
|
-
# Micro::Case
|
1292
|
-
# Micro::Case
|
1311
|
+
# Interactor::Organizer 2.163k i/100ms
|
1312
|
+
# Micro::Cases.flow([]) 13.158k i/100ms
|
1313
|
+
# Micro::Case flow in a class 8.400k i/100ms
|
1314
|
+
# Micro::Case including the class 8.008k i/100ms
|
1315
|
+
# Micro::Case::Result#| 17.151k i/100ms
|
1316
|
+
# Micro::Case::Result#then 14.121k i/100ms
|
1293
1317
|
|
1294
1318
|
# Calculating -------------------------------------
|
1295
|
-
# Interactor::Organizer
|
1296
|
-
# Micro::Cases.flow([])
|
1297
|
-
# Micro::
|
1298
|
-
# Micro::Case
|
1299
|
-
# Micro::Case
|
1319
|
+
# Interactor::Organizer 22.467k (± 1.8%) i/s - 112.476k in 5.007787s
|
1320
|
+
# Micro::Cases.flow([]) 133.183k (± 1.5%) i/s - 671.058k in 5.039815s
|
1321
|
+
# Micro::Case flow in a class 84.083k (± 1.8%) i/s - 428.400k in 5.096623s
|
1322
|
+
# Micro::Case including the class 80.574k (± 1.6%) i/s - 408.408k in 5.070029s
|
1323
|
+
# Micro::Case::Result#| 172.734k (± 1.1%) i/s - 874.701k in 5.064429s
|
1324
|
+
# Micro::Case::Result#then 139.799k (± 1.7%) i/s - 706.050k in 5.052035s
|
1300
1325
|
|
1301
1326
|
# Comparison:
|
1302
|
-
# Micro::Case
|
1303
|
-
# Micro::Case
|
1304
|
-
# Micro::Cases.flow([]):
|
1305
|
-
# Micro::
|
1306
|
-
#
|
1327
|
+
# Micro::Case::Result#|: 172734.4 i/s
|
1328
|
+
# Micro::Case::Result#then: 139799.0 i/s - 1.24x (± 0.00) slower
|
1329
|
+
# Micro::Cases.flow([]): 133182.9 i/s - 1.30x (± 0.00) slower
|
1330
|
+
# Micro::Case flow in a class: 84082.6 i/s - 2.05x (± 0.00) slower
|
1331
|
+
# Micro::Case including the class: 80574.3 i/s - 2.14x (± 0.00) slower
|
1332
|
+
# Interactor::Organizer: 22467.4 i/s - 7.69x (± 0.00) slower
|
1307
1333
|
```
|
1308
1334
|
</details>
|
1309
1335
|
|
@@ -1312,29 +1338,72 @@ https://github.com/serradura/u-case/blob/main/benchmarks/use_case/with_failure_r
|
|
1312
1338
|
|
1313
1339
|
```ruby
|
1314
1340
|
# Warming up --------------------------------------
|
1315
|
-
# Interactor::Organizer
|
1316
|
-
# Micro::Cases.flow([])
|
1317
|
-
# Micro::
|
1318
|
-
# Micro::Case
|
1319
|
-
# Micro::Case
|
1341
|
+
# Interactor::Organizer 2.167k i/100ms
|
1342
|
+
# Micro::Cases.flow([]) 11.797k i/100ms
|
1343
|
+
# Micro::Case flow in a class 7.783k i/100ms
|
1344
|
+
# Micro::Case including the class 7.097k i/100ms
|
1345
|
+
# Micro::Case::Result#| 14.398k i/100ms
|
1346
|
+
# Micro::Case::Result#then 12.719k i/100ms
|
1320
1347
|
|
1321
1348
|
# Calculating -------------------------------------
|
1322
|
-
# Interactor::Organizer
|
1323
|
-
# Micro::Cases.flow([])
|
1324
|
-
# Micro::
|
1325
|
-
# Micro::Case
|
1326
|
-
# Micro::Case
|
1349
|
+
# Interactor::Organizer 21.863k (± 2.5%) i/s - 110.517k in 5.058420s
|
1350
|
+
# Micro::Cases.flow([]) 118.124k (± 1.8%) i/s - 601.647k in 5.095102s
|
1351
|
+
# Micro::Case flow in a class 77.801k (± 1.5%) i/s - 389.150k in 5.003002s
|
1352
|
+
# Micro::Case including the class 73.533k (± 2.1%) i/s - 369.044k in 5.021076s
|
1353
|
+
# Micro::Case::Result#| 153.746k (± 1.5%) i/s - 777.492k in 5.058177s
|
1354
|
+
# Micro::Case::Result#then 126.897k (± 1.7%) i/s - 635.950k in 5.013059s
|
1327
1355
|
|
1328
1356
|
# Comparison:
|
1329
|
-
# Micro::Case
|
1330
|
-
# Micro::Case
|
1331
|
-
# Micro::Cases
|
1332
|
-
# Micro::
|
1333
|
-
#
|
1357
|
+
# Micro::Case::Result#|: 153745.6 i/s
|
1358
|
+
# Micro::Case::Result#then: 126896.6 i/s - 1.21x (± 0.00) slower
|
1359
|
+
# Micro::Cases.flow([]): 118123.9 i/s - 1.30x (± 0.00) slower
|
1360
|
+
# Micro::Case flow in a class: 77800.7 i/s - 1.98x (± 0.00) slower
|
1361
|
+
# Micro::Case including the class: 73532.9 i/s - 2.09x (± 0.00) slower
|
1362
|
+
# Interactor::Organizer: 21862.9 i/s - 7.03x (± 0.00) slower
|
1334
1363
|
```
|
1335
1364
|
</details>
|
1336
1365
|
|
1337
|
-
https://github.com/serradura/u-case/
|
1366
|
+
https://github.com/serradura/u-case/blob/main/benchmarks/perfomance/flow/
|
1367
|
+
|
1368
|
+
[⬆️ Voltar para o índice](#índice-)
|
1369
|
+
|
1370
|
+
### Execuntando os benchmarks
|
1371
|
+
|
1372
|
+
#### Performance (Benchmarks IPS)
|
1373
|
+
|
1374
|
+
Clone este repositório e acesse a sua pasta, então execute os comandos abaixo:
|
1375
|
+
|
1376
|
+
**Casos de uso**
|
1377
|
+
|
1378
|
+
```sh
|
1379
|
+
ruby benchmarks/perfomance/use_case/failure_results.rb
|
1380
|
+
ruby benchmarks/perfomance/use_case/success_results.rb
|
1381
|
+
```
|
1382
|
+
|
1383
|
+
**Flows**
|
1384
|
+
|
1385
|
+
```sh
|
1386
|
+
ruby benchmarks/perfomance/flow/failure_results.rb
|
1387
|
+
ruby benchmarks/perfomance/flow/success_results.rb
|
1388
|
+
```
|
1389
|
+
|
1390
|
+
#### Memory profiling
|
1391
|
+
|
1392
|
+
**Casos de uso**
|
1393
|
+
|
1394
|
+
```sh
|
1395
|
+
./benchmarks/memory/use_case/success/with_transitions/analyze.sh
|
1396
|
+
./benchmarks/memory/use_case/success/without_transitions/analyze.sh
|
1397
|
+
```
|
1398
|
+
|
1399
|
+
**Flows**
|
1400
|
+
|
1401
|
+
```sh
|
1402
|
+
./benchmarks/memory/flow/success/with_transitions/analyze.sh
|
1403
|
+
./benchmarks/memory/flow/success/without_transitions/analyze.sh
|
1404
|
+
```
|
1405
|
+
|
1406
|
+
[⬆️ Voltar para o índice](#índice-)
|
1338
1407
|
|
1339
1408
|
### Comparações
|
1340
1409
|
|
@@ -1347,24 +1416,24 @@ Confira as implementações do mesmo caso de uso com diferentes gems/abstraçõe
|
|
1347
1416
|
|
1348
1417
|
## Exemplos
|
1349
1418
|
|
1350
|
-
### 1️⃣
|
1419
|
+
### 1️⃣ Criação de usuários
|
1420
|
+
|
1421
|
+
> 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`.
|
1422
|
+
>
|
1423
|
+
> Link: https://github.com/serradura/u-case/blob/main/examples/users_creation
|
1424
|
+
|
1425
|
+
### 2️⃣ Rails App (API)
|
1351
1426
|
|
1352
1427
|
> 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
1428
|
>
|
1354
1429
|
> Link: https://github.com/serradura/from-fat-controllers-to-use-cases
|
1355
1430
|
|
1356
|
-
###
|
1431
|
+
### 3️⃣ CLI calculator
|
1357
1432
|
|
1358
1433
|
> 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
1434
|
>
|
1360
1435
|
> Link: https://github.com/serradura/u-case/tree/main/examples/calculator
|
1361
1436
|
|
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
1437
|
### 4️⃣ Interceptando exceções dentro dos casos de uso
|
1369
1438
|
|
1370
1439
|
> Link: https://github.com/serradura/u-case/blob/main/examples/rescuing_exceptions.rb
|