[Architektura oprogramowania] Wzorzec projektowy rurociągu – od zera do bohatera

W tym artykule poznamy różne sposoby implementacji wzorca projektowego rurociągu, począwszy od podstaw do bardziej złożonych rozwiązań.

Wzorzec rurociągu

Wzorzec rurociągu to wzorzec projektowy oprogramowania, który zapewnia możliwość budowania i wykonywania sekwencji operacji.

https://www.hojjatk.com/2012/11/chain-of-responsibility-pipeline-design.html

Wzorzec ten lepiej stosować w połączeniu z wzorcem plugin, aby dynamicznie budować potok przy starcie aplikacji.

Sekwencja

Najbardziej podstawową implementacją potoku byłaby prosta sekwencja operacji.

Interfejs operacji może być wywołany w celu przetworzenia danych.

Potok przetwarza każdą operację po kolei. Klasa rurociągu implementuje również interfejs IOperation, więc można je łączyć.

Operację można napisać w dedykowanej klasie.

Albo użyć wrappera, aby automatycznie utworzyć operację z lambdy.

Operacje w potoku powinny być zarejestrowane przed wywołaniem potoku.

Przerywacz obwodu

Pierwszą cechą, którą chcesz dodać do swojego potoku, jest dodanie przerywacza obwodu.

Każda operacja zwróci wynik : niepowodzenie lub sukces.

Jeśli operacja się nie powiedzie, wykonanie potoku powinno się zatrzymać.

Asynchroniczne

Innym wymaganiem może być posiadanie potoku, który radzi sobie z operacjami asynchronicznymi.

Każda operacja będzie teraz musiała wywołać następną operację w potoku, po zakończeniu przetwarzania danych.

Potok jest nieco bardziej złożony, ponieważ musi ustawić następną operację, gdy nowa operacja jest zarejestrowana. Innym rozwiązaniem jest użycie konstruktora.

Ta operacja jest asynchroniczna i będzie działać w dedykowanym wątku, kiedy skończy się czas, wywoła następną operację, aby kontynuować potok.

Operacja generyczna może być używana zarówno z prostą akcją, lub użyć wbudowanego wyłącznika, jeśli używasz funkcji.

Ten prosty przykład wykorzystuje kilka z zaimplementowanych przez nas funkcji.

Teraz już wiesz jak uczynić swój potok asynchronicznym !

Byłoby jeszcze lepiej, gdybyś miał kolejne wywołanie zwrotne do poprzedniej operacji, abyś mógł mieć wynik płynący przeciwprądowo przez rurociąg.

Wtyczka

Głównym powodem używania wzorca projektowego rurociągu jest często wymóg możliwości dodawania wtyczek, które będą albo dołączać operacje do istniejącego rurociągu, albo zaczepiać operację w jego środku.

Potok jest naprawdę podstawowy, ale tym razem operacje są wyeksponowane.

Przyjrzyjmijmy prostą aplikację z potokiem, który będzie wyświetlał tylko 3 kroki w konsoli. Ta aplikacja obsługuje również wtyczki do modyfikowania potoku.

Pierwsza wtyczka zaczepi inną operację w drugim slocie potoku.

Druga wtyczka dołączy nową operację na końcu potoku.

Po złożeniu aplikacji i pluginów w całość, możemy wywołać potok.

Batch

Inną przydatną funkcją jest możliwość przetwarzania danych wsadowych w tym samym potoku niż pojedynczych elementów.

Potok wsadowy zawija potok i wywołuje każdą operację na każdym elemencie.

Każdy element jest zawijany, dzięki czemu możemy zapamiętać wynik działania potoku wsadowego.

Ta operacja sprawdza, czy liczba całkowita ma wymagany rząd wielkości.

Potok będzie sprawdzał rząd wielkości partii liczb całkowitych.

Potok wywołuje następną operację tylko dla elementów, które nie zawiodły.

Wysokowydajny potok

Pattern projektowy potoku może również odnosić się do znacznie bardziej specyficznej i zorientowanej na wydajność architektury oprogramowania.

Niektóre projekty wykorzystują potok do optymalizacji przetwarzania ogromnej ilości danych poprzez uruchamianie każdej operacji potoku w dedykowanym wątku.

Każdy wątek będzie konsumował i produkował dane ze współbieżnej kolejki, która będzie pełniła rolę bufora.

Tym razem wykorzystamy operacje asynchroniczne z użyciem circuit-breakera.

Jeśli operacja się powiedzie, powinna wywołać next, lub zakończyć, jeśli się nie powiodła.

Potok jest zaprojektowany tak, aby ominąć circuit-breaker. Sukces lub niepowodzenie, zawsze będzie kontynuował sekwencję potoku nadrzędnego i wywoła następną operację.

Scenariusz jest nieco złożony, więc nie wyjaśnię wszystkiego. Chodzi o to, aby mieć różne wątki do przetwarzania przychodzących zamówień. Po zakończeniu przetwarzania zamówienia, sprawdzamy status zamówienia.

Każdy procesor zamówienia jest izolowany w dedykowanym wątku, dzięki czemu można zoptymalizować sposób przechowywania danych i mieć bezpośredni dostęp do pamięci bez użycia blokady.

Procesor zamówień płatności jest jedynym wątkiem, który może uzyskać dostęp do sald użytkowników. Może on uzyskać lub zaktualizować dowolne saldo bez obaw o kwestie współbieżności.

Potok przetwarza sekwencję operacji tak szybko, jak to możliwe.

Wniosek

Wzorzec projektowy Pipeline ma wiele bardzo różnych sposobów implementacji, od prostego Chain of Command do bardziej złożonego Workflow.

Można wymagać wielu funkcji, takich jak circuit-breaker, asynchroniczny lub buforowy, ale przez większość czasu, chcesz używać rurociągów, gdy chcesz mieć wtyczki, które mogą zahaczać w strumieniu wykonawczym rurociągu.

.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.