Jak ważne jest stworzenie warstwy usługi?

68

Zacząłem budować aplikację w 3 warstwach (DAL, BL, UI) [obsługuje głównie CRM, niektóre raporty sprzedaży i zapasy].

Kolega powiedział mi, że muszę przejść do wzorca warstwy usługi, że programiści przyszli do wzorca usługi z ich doświadczenia i jest to lepsze podejście do projektowania większości aplikacji. Powiedział, że w ten sposób będzie łatwiej utrzymać aplikację w przyszłości.

Osobiście mam wrażenie, że to tylko komplikuje sprawę i nie widziałem wiele korzyści, które by to uzasadniały.

Ta aplikacja ma dodatkowy mały częściowy interfejs użytkownika, który wykorzystuje niektóre (ale tylko nieliczne) funkcje aplikacji komputerowej, więc znalazłem, że duplikowałem trochę kodu (ale niewiele). Po prostu z powodu jakiegoś duplikacji kodu nie przekonwertowałbym go na zorientowany na usługi, ale powiedział, że powinienem go mimo to użyć, ponieważ ogólnie jest to bardzo dobra architektura, dlaczego programiści tak bardzo pasjonują się usługami?

Próbowałem google go, ale nadal jestem zdezorientowany i nie mogę zdecydować, co robić.

BornToCode
źródło

Odpowiedzi:

58

Książka Martina Fowlera „Patterns of Enterprise Architecture” stwierdza:

Łatwiej odpowiedzieć na pytanie, kiedy nie należy go używać. Prawdopodobnie nie potrzebujesz warstwy usług, jeśli logika biznesowa aplikacji będzie miała tylko jednego rodzaju klienta - powiedzmy interfejs użytkownika - a odpowiedzi na przypadki użycia nie wymagają wielu zasobów transakcyjnych. [...]

Ale gdy tylko wyobrazisz sobie drugiego rodzaju klienta lub drugi zasób transakcyjny w odpowiedziach na przypadki użycia, opłaca się projektować w warstwie usług od samego początku.

Korzyści, jakie zapewnia warstwa usług, to to, że definiuje wspólny zestaw operacji aplikacji dostępnych dla różnych klientów i koordynuje reakcję w każdej operacji. Jeśli masz aplikację, która ma więcej niż jeden rodzaj klienta, który korzysta z logiki biznesowej i ma złożone przypadki użycia obejmujące wiele zasobów transakcyjnych - warto dołączyć warstwę usług z zarządzanymi transakcjami.

Z CRM, sprzedażą i zapasami będzie wiele przypadków użycia typu CRUD, z których prawie zawsze istnieje bezpośrednia korespondencja z operacjami warstwy usług. Odpowiedzi na tworzenie, aktualizację lub usuwanie obiektu domeny powinny być koordynowane i przeprowadzane w sposób atomowy za pomocą operacji warstwy usługi.

Kolejną korzyścią z posiadania warstwy usług jest to, że można ją zaprojektować do lokalnego lub zdalnego wywoływania, lub w obu przypadkach - i daje to elastyczność. Wzór ten stanowi podstawę do enkapsulowanej implementacji logiki biznesowej aplikacji i wywoływania tej logiki przez różnych klientów w spójny sposób. Oznacza to również zmniejszenie / usunięcie duplikacji kodu, ponieważ klienci korzystają z tych samych wspólnych usług. Możesz także potencjalnie zmniejszyć koszty utrzymania - ponieważ kiedy zmienia się logika biznesowa, (zazwyczaj) wystarczy zmienić usługę, a nie każdego klienta.

Podsumowując, dobrze jest użyć warstwy usług - więcej, więc myślę, że w twoim przykładzie podałeś, ponieważ wygląda na to, że masz wielu klientów logiki biznesowej.

Deco
źródło
2
Co ciekawe, Martin Fowler opowiada się przeciwko temu samemu interfejsowi do wywoływania lokalnego i zdalnego, argumentując, że ogromna różnica w wydajności zdalnego wywoływania wymusza bardziej gruboziarnisty interfejs.
psr
Nie do końca zrozumiałem twój akapit With CRM, Sales and Inventory there will be a lot of CRUD-type use cases of which there is almost always a one-to-one correspondence with Service Layer operations- jeśli chodzi o wiele interfejsów użytkownika, w jaki sposób wchodzi tutaj CRUD? A gdybym nie potrzebował wielu interfejsów użytkownika, mimo że CRUD dobrze współpracuje z usługami, nadal nie stworzyłbym warstwy usługi, jeśli dobrze zrozumiałem, i naprawdę mam nadzieję, że tak, ponieważ wolę zachować prostotę (warstwa usługi to bałagan do mojej niedoświadczonej opinii)
BornToCode
4
W takich przypadkach rzadko zdarza się, że może skorzystać z niego tylko jeden klient. Jeśli masz tylko jeden interfejs użytkownika, mogę wymyślić dwa powody, dla których nadal możesz chcieć warstwy usług: bezpieczeństwo i możliwość ponownego użycia. W typowej konfiguracji dla przedsiębiorstw aplikacja UI byłaby dostępna dla klientów zewnętrznych, a warstwa usługi dostępna tylko w sieci. Tak więc serwer sieciowy delaguje pracę do zablokowanej części sieci. W przykładzie sprzedaży możesz użyć ponownie, jeśli przejmiesz sprzedaż ze swojej witryny i przejdziesz na eBay lub Amazon. Teraz masz jeden interfejs użytkownika, ale wielu klientów.
Phil Patterson,
5
Aby dodać do komentarza @PhilPatterson. Wielu klientów nie musi opierać się tylko na interfejsie użytkownika. Pomyśl o usługach internetowych lub bibliotekach - mogą to być także klienci. Twój interfejs użytkownika może korzystać z warstwy usług, a także z usług oprogramowania, które pakujesz i pozwolić komuś innemu.
Deco
czy możesz podać przykład warstwy usługi?
user962206
34

Dodanie warstwy usługi, ponieważ dokonałeś oceny pomysłu i stwierdziłeś, że jest to najlepsze podejście: dobre

Dodanie warstwy usług, ponieważ to właśnie robią wszystkie fajne dzieci: źle

Jeśli twoje jelita mówią, że nie potrzebujesz, nie rób go.

Jednym z bardziej rozczarowujących wydarzeń w świecie programowania w ciągu ostatnich 10 lat jest to, że stało się irytujące zorientowane na „modę”, a ludzie podążają za trendami i bandwagonami, jakby byli butami w tym sezonie. Nie wpadnij w tę pułapkę. Ponieważ w przyszłym sezonie „wszyscy” powiedzą ci, że powinieneś to zaprojektować w inny sposób.

Z warstwą usług nie ma nic złego lub niewłaściwego - jest to szczególne podejście, którego przydatność należy ocenić pod kątem technicznych zalet dla danego projektu. Nie czuj się zmuszony do zastępowania opinii innych osób własnym osądem.

Grandmaster B.
źródło
27
To w ogóle nie dotyczy tematu, po prostu składa ogólne oświadczenie / rant na temat praktyk programistycznych, które po zastąpieniu kilku słów mogą odnosić się do niemal każdego pytania na tej stronie. Po przeczytaniu tej odpowiedzi, nie jestem nawet przekonany, że wiesz dokładnie, co warstwa usługa jest .
Aaronaught
12
Z pewnością można go zastosować do innych pytań ... nie czyni to mniej prawdziwym. Faktem jest, że ani ty, ani ja nie mamy w pobliżu niezbędnego kontekstu, aby określić, czego potrzebuje w swoim projekcie, więc powiedzenie mu tak, że potrzebuje tego, lub nie, nie jest po prostu zgadywaniem i nieprofesjonalne. To, czego potrzebuje OP, to trochę moralnego wsparcia, aby podejmować decyzje, o których wie, że są właściwe.
GrandmasterB
5
@Aaronaught Niezależnie od poprawności odpowiedzi, nadal zasadniczo odpowiada na główne pytanie: „Jak ważna jest warstwa usługi?”. Twierdzi, że wcale nie jest niezbędny i że może to tylko moda. Jeśli nie zgadzasz się z odpowiedzią, proszę zagłosować.
wałek klonowy
2
@GrandmasterB Argumentowałbym, że mody są dobre w tworzeniu oprogramowania. Większość programistów jest zbyt świeża lub zbyt niekompetentna, aby podejmować świadome decyzje dotyczące projektowania i architektury. Nadal oczekujemy, że okażą się nieco pozorami działającego oprogramowania, więc skakanie na modę i bycie zgodnym z kiepskim wyborem projektu jest znacznie lepsze i łatwiejsze w utrzymaniu niż sposób, w jaki robiono to lata temu, w którym kowbojskim kodem byłby wszystko nie rozumiem ani nie doceniam.
wałek klonowy
10
@maple_shaft Aby wyjaśnić, nie mówię, że warstwy usług są modne. Mówię, w oparciu o sposób padło pytanie, które wydaje się nie Faddish / moda / modą zachowanie ze strony swoich kolegów, aby pchnąć go do stosując architekturę robi on, że jest warrented w swoim projekcie. Wyjaśniam to w mojej odpowiedzi. Widzę warstwy usług (lub dowolną inną koncepcję) jako takie - neutralne koncepcje, których przydatność należy oceniać indywidualnie dla poszczególnych projektów. Nie należy ich stosować / stosować, gdy według własnego osądu nie są one potrzebne.
GrandmasterB
22

Istnieje wiele czynników, które wpływają na decyzję o utworzeniu warstwy usług. W przeszłości tworzyłem warstwy usług z następujących powodów.

  1. Kod, który musi być ponownie użyty przez wielu klientów.
  2. Biblioteki stron trzecich, na które mamy ograniczone licencje.
  3. Strony trzecie, które potrzebują punktu integracji z naszym systemem.
  4. Centralizacja zduplikowanej logiki biznesowej.

Przypadek 1: Tworzysz podstawową funkcjonalność, z której musi korzystać mnóstwo różnych klientów. Warstwa usług ma wbudowaną funkcjonalność dla różnych klientów, dzięki której możesz natychmiast skorzystać z dostarczonej funkcjonalności.

Przypadek 2: zwykle przechowujesz kod w przestrzeni aplikacji, ale korzystasz z biblioteki innej firmy, na którą masz ograniczone licencje. W takim przypadku masz zasób, z którego chciałbyś korzystać wszędzie, ale tylko ograniczoną liczbę z nich. Jeśli hostujesz go za usługą, cała Twoja organizacja może korzystać z niego ze swoich aplikacji bez konieczności kupowania licencji dla każdego hostingu.

Przypadek 3: Budujesz funkcjonalność, aby osoby trzecie mogły się z Tobą komunikować. W twoim przykładzie możesz skonfigurować punkt końcowy zapasów, aby umożliwić dostawcom przekazywanie wiadomości o przychodzących wysyłkach produktów.

Przypadek 4: Przeanalizowałeś swój kod w całym przedsiębiorstwie i odkryłeś, że oddzielne zespoły stworzyły to samo (tylko nieco inaczej wdrożone). Dzięki warstwie usług możesz wybrać najlepsze podejście, a teraz możesz wdrożyć ten sam proces we wszystkich zespołach, każąc im zadzwonić do serwisu. Kolejną korzyścią z centralizacji logiki jest znalezienie błędów. Teraz możesz wdrożyć poprawkę raz, a wszyscy klienci korzystają z korzyści w tym samym czasie.

Biorąc to wszystko pod uwagę, istnieją potencjalne negatywy dla warstwy usług.

  1. Dodaje złożoność systemu. Gdzie wcześniej miałeś tylko jedną aplikację do debugowania, teraz masz dwie. Problemy z produkcją wymagają sprawdzenia ustawień aplikacji klienckiej, ustawień aplikacji usługowych lub problemów z komunikacją między innymi poprawnie skonfigurowanymi aplikacjami klienckimi i serwerowymi. Może to być trudne, jeśli nigdy wcześniej tego nie robiłeś.
  2. Jeden punkt awarii. Jeśli wystąpi awaria usługi, dotyczy to wszystkich klientów. Gdy kod nie jest wdrażany w ten sposób, ryzyko może być mniejsze (choć istnieją sposoby na złagodzenie tego).
  3. Wersjonowanie może być trudniejsze. Jeśli masz jedną aplikację korzystającą z usługi wdrażającej interfejs, zmiany można wprowadzić w tym samym czasie między nimi. Jeśli masz teraz wielu klientów, musisz zarządzać, kto jest na V1, a kto na V2, i koordynować usuwanie V1 (gdy wiesz, że wszyscy zaktualizowali się do V2).

Chodzi przede wszystkim o to, że nie zawsze jest to szybkie, aby zorientować usługę na system. Z mojego doświadczenia wynika, że ​​zazwyczaj jest to dobry pomysł (zazwyczaj tworzę aplikacje w taki sposób), ale nie jest to automatyczna decyzja. Na koniec dnia musisz rozważyć zalety i wady i podjąć decyzję odpowiednią dla Twojej sytuacji.

Phil Patterson
źródło
2
+1 Dziękujemy za pouczającą odpowiedź. Naprawdę miałem wątpliwości, czy przyjmie twoją odpowiedź lub odpowiedź Deco. W końcu, ponieważ nie jestem zbyt doświadczony, zdecydowałem się wybrać odpowiedź, która uzyska najwięcej pozytywnych opinii. Nadal uważam, że twoja odpowiedź zasługuje na więcej pochwał. W każdym razie naprawdę doceniam to, że podzieliłeś się swoją wiedzą i doświadczeniem. Dziękuję Ci!
BornToCode,
1
Proszę bardzo! Główną kwestią, którą należy odjąć od obu odpowiedzi, jest to, że (głównie) chodzi o rozwiązywanie problemów związanych z konserwacją, mając wielu klientów, którzy muszą zrobić to samo. Im większa liczba klientów korzystających z usługi, tym większy zysk za utrzymanie.
Phil Patterson
1
Istnieje również bezpieczeństwo - warstwy usług mogą zapewnić kolejną ścianę dla hakerów, aby mogli dostać się do skarbu w DB. Brak warstw usług jest prawdopodobnie przyczyną, dla której tak wiele witryn ma ogromne naruszenia, a usługa jest w środku, a hakerzy dostają znacznie mniej danych, zanim zostaną wykryte.
gbjbaanb
6

Większość warstw usług, które widziałem, to kompletny bałagan. Usługi mają zwykle wiele różnych metod, 1500 LOC nie jest rzadkością. Różne metody nie mają ze sobą nic wspólnego, ale dzielą kod. Skutkuje to wysokim sprzężeniem , niską kohezją . Narusza to także OCP , ponieważ za każdym razem, gdy potrzebna jest nowa operacja, musisz zmodyfikować kod zamiast rozszerzać bazę kodu. Dobrze zbudowana warstwa usług jest teoretycznie możliwa, ale nigdy nie widziałem jej w praktyce.

CQRS rozwiązuje te problemy i zapobiega tworzeniu jednej z tych warstw usług proceduralnych.

Jeroen
źródło
2
Dobrze skonstruowany według czyich standardów? Z pewnością według standardów OO interfejs warstwy usług jest kompletnym wrakiem bałaganu. Z perspektywy funkcjonalnej lub proceduralnej zachęca to do pięknego, warstwowego podejścia do projektowania. Myślę, że największe rozłączanie się ludzi z warstwami usług polega na tym, że zachęcają one do zastosowania bezpaństwowej aplikacji opartej na transakcjach i zniechęcają do podejścia czysto obiektowego. Rozumiem obie strony argumentu.
wałek klonowy
6

Dodanie interfejsu (warstwa usługi jest rodzajem interfejsu) zajmuje dużo czasu. Dobry zajmuje dużo czasu na zaprojektowanie i przetestowanie. Bardzo ważne jest, aby zrobić to poprawnie przy pierwszej próbie, ponieważ późniejsza zmiana powoduje uszkodzenie wszystkich klientów. Weź również pod uwagę, że prawdopodobnie nie będziesz wiedział, co musi być w tym interfejsie, dopóki nie będziesz mieć drugiego klienta z nieco innymi potrzebami. Utrzymanie usługi jest samo w sobie niekończącym się projektem.

W większości organizacji, jeśli udasz się do sponsora biznesowego i zapytasz ich: „Czy chcesz, aby inne działy mogły skorzystać z (ponownego wykorzystania) tego systemu, który tworzymy przy Twoim budżecie?” będą się z ciebie śmiać. Spraw, by najpierw działał dla Twojego sponsora biznesowego, a następnie zacznij kręcić się w kółko, ponownie wykorzystując ten kod (w czasie własnego działu).

Jeśli wiesz, że pisana dziś funkcjonalność zostanie ponownie wykorzystana przez wielu różnych klientów usług, rozważ zaprojektowanie warstwy usługi od pierwszego dnia. Jeśli nie masz pewności lub w projekcie jest wiele niewiadomych, najpierw uruchom coś prostego, a następnie podziel go na obsługę i klienta, jeśli masz czas i budżet. O wiele łatwiej jest uzyskać interfejs serwisowy za pierwszym razem, gdy zaczynasz z działającym systemem.

PS Jeśli pracujesz w Javie, Joshua Bloch ma wiele fantastycznych porad dotyczących interfejsu w swojej książce Effective Java.

GlenPeterson
źródło
Świetna odpowiedź bez jałowych teorii.
danilo
2

Zgadzam się z Tobą. Jeśli używasz jednego interfejsu użytkownika, nie musisz dołączać jeszcze jednej warstwy.

DAL, BL i interfejs użytkownika / kontroler to dobre połączenie do zaprojektowania aplikacji. Jeśli planujesz używać jednego interfejsu użytkownika, nie musisz przygotowywać dodatkowej warstwy. Włączenie 1 dodatkowej warstwy do aplikacji tylko zwiększa wysiłek / czas programowania.

Innym schenerio jest użycie wielu interfejsów użytkownika w swojej aplikacji, w tym przypadku dobrze jest mieć warstwę usługi do obsługi interfejsów użytkownika.

Przepełnienie stosu: dyskusja na temat wzorca warstwy usługi

Satish Pandey
źródło
Czy sugerujesz więc, że przy każdej złożonej aplikacji należy rozwijać warstwę usług, a nie tylko zadowolić się warstwami DAL, BL, UI?
BornToCode,
W przypadku wielu interfejsów użytkownika musimy dołączyć warstwę usług. W twoim przypadku nie sądzę, że trzeba przygotować nową warstwę. Zwiększa to tylko złożoność aplikacji.
Satish Pandey
0

Kwestionowałbym, że twoja BL jest twoją warstwą usług. Centralne miejsce, w którym znajduje się logika biznesowa. Powinna to być biblioteka DLL, z której może korzystać każdy, kto potrzebuje takiej logiki. Następnie możesz nałożyć na nią warstwę interfejsu API, jeśli Twoja aplikacja będzie miała inny interfejs użytkownika.

użytkownik441521
źródło