# Pipeline pattern ## O que é <br/> <br/> ![](https://i.imgur.com/wJKeRs9.png) Pipeline patter permite o processamento em uma série de etapas, fornecendo uma entrada inicial e passando a saída processada para ser usada pelos próximos estágios. 1 - Organização de processos computacionais como sequencia 2 - A saída de um processo é a entrada do próximo processo <br/> <br/> <br/> ## Usamos mais do que imaginamos <br/> <br/> ![](https://i.imgur.com/a5X46Oz.png) ### Streams 1 - O streams nos fornece uma forma de forma de fazer diversas etapas sequenciais onde Parte da DOC de Stream: > Um fluxo não é uma estrutura de dados que armazena elementos; em vez disso, ele transmite elementos de uma fonte, como uma estrutura de dados, uma matriz, uma função geradora ou um canal de I/O, por meio de um pipeline de operações computacionais. ![](https://i.imgur.com/6csxZun.png) ### Benefícios ![](https://i.imgur.com/a8N0Msy.png) - Execute estágios individuais que geram um valor final. - Adicione legibilidade à sequência complexa de operações fornecendo um construtor fluente como uma interface. - Melhore a testabilidade do código, pois os processos provavelmente farão uma única coisa, em conformidade com o Princípio de Responsabilidade Única (SRP) ## Real life <br/><br/> ![](https://i.imgur.com/smw0ycn.png) ### DebitService ![](https://i.imgur.com/9KXknMo.png) ``` java @Slf4j @Service @AllArgsConstructor @ConditionalOnProperty(value="service.debit-service", havingValue = "v2") public class DebitService implements IDebitService { private final PixConfig pixConfig; private final MetricsService metricsService; private final PipelineImpl pipelineProcessPayment; private final SetEntryValueToCreditorIfExistsStepOnSuccess setEntryValueToCreditorIfExistsStep; private final GetOriginTransactionStepOnSuccess getOriginTransactionStep; private final SetTransactionIdIfEmptyStepOnSuccess setTransactionIdIfEmptyStep; private final SetGeolocationIfNullStepOnSuccess setGeolocationIfNullStep; private final SetEndToEndIdIfNullStepOnSuccess setEndToEndIdIfNullStep; private final ValidateAndSaveInEndToEndIdCacheStepOnSuccess validateAndSaveInEndToEndIdCacheStep; private final SetPaymentTypeToManualIfNullStepOnSuccess setPaymentTypeToManualIfNullStep; private final SetNatureTypeToRealTimeIfNullStepOnSuccess setNatureTypeToRealTimeIfNullStep; private final ValidateIfIsNotMedOperationStepOnSuccess validateIfIsNotMedOperationStep; private final RemoveSpecialCharacteresOfDescriptionStepOnSuccess removeSpecialCharacteresOfDescriptionStep; private final ValidateIfIsQrCodeStepOnSuccess validateIfIsQrCodeStep; private final UpdateAccountNumberAliasStepOnSuccess updateAccountNumberAliasStep; private final GetCoreBankingStepOnSuccess getCoreBankingStep; private final ValidateTransactionStepOnSuccessStep validateTransactionStep; private final ValidateTransactionLimitStepOnSuccess validateTransactionLimitStep; private final SendToCoreStepOnSuccess sendToCoreStep; private final SaveTransactionStepOnSuccess saveTransactionStep; private final ProcessPaymentStep processPaymentStep; private final PipelineImpl pipelineErrorHandler; private final DeleteConstrainStep deleteConstrainStep; @Override public CreateTransferResponse sendPayment(CreateTransferDTO request) { metricsService.increaseCounter("pagamento_iniciado"); log.info("Iniciando transação de débito para {}", request); if (BooleanUtils.isFalse(pixConfig.isDebitEnabled())) { final String errorMessage = "error.disabledDebit"; metricsService.increaseCounter("pagamento_erro", "error_message", errorMessage); throw new BusinessException(errorMessage); } try { pipelineProcessPayment .addStep(setEntryValueToCreditorIfExistsStep) .addStep(getOriginTransactionStep) .addStep(setTransactionIdIfEmptyStep) .addStep(setGeolocationIfNullStep) .addStep(setEndToEndIdIfNullStep) .addStep(validateAndSaveInEndToEndIdCacheStep) .addStep(setPaymentTypeToManualIfNullStep) .addStep(setNatureTypeToRealTimeIfNullStep) .addStep(validateIfIsNotMedOperationStep) .addStep(removeSpecialCharacteresOfDescriptionStep) .addStep(validateIfIsQrCodeStep) .addStep(updateAccountNumberAliasStep) .addStep(getCoreBankingStep) .addStep(validateTransactionStep) .addStep(validateTransactionLimitStep) .addStep(sendToCoreStep) .addStep(saveTransactionStep) .addStep(processPaymentStep) .execute(request); final CreateTransferResponse response = new CreateTransferResponse(request.getTransactionId(), request.getEndToEndId()); log.info("Transação concluída com sucesso: {}", response); return response; } catch (Exception exception) { pipelineErrorHandler .addStep(deleteConstrainStep) .execute(request, exception); throw exception; } } } ``` --- #### Referências : https://martinfowler.com/articles/collection-pipeline/ https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html https://java-design-patterns.com/patterns/pipeline/