Warstwa usługi aplikacji wywołująca funkcje bazy danych. Zła architektura?

11

Scenariusz:

  • Stos: Java, Spring, Hibernacja.
  • Model: aplikacja klient-serwer.
  • Wzór: Model-View-Controller (MVC).

Klasy warstwy usług mają trzy zachowania:

  1. Niektóre usługi zawierają regułę biznesową w ramach metod i delegują trwałość aplikacji. Lubić:

    EntityManager.save (encja);

  2. Niektóre usługi po prostu wywołują funkcję bazy danych (przekazują parametry), takie jak:

    CallableStatement cls = con.prepareCall („{call databaseFunction (args)}”);

  3. Niektóre usługi mają metody z oboma zachowaniami.

Moje pytania:

  1. Czy istnieje problem z wywoływaniem funkcji baz danych bezpośrednio przez aplikacje? Czy nie jest to uważane za złą praktykę? Jaki byłby model architektury mający zastosowanie do takiego projektu?
  2. Czy jest jakiś problem z mieszaniem zachowań w tej samej usłudze? Takie jak transakcje i spójność?
  3. Czy w przypadku konserwacji enkapsulacja sprawia, że ​​programiście nie jest w stanie zmienić funkcji w bazie danych? Jak tego uniknąć?
  4. Czy ten scenariusz zdarza się w innych aplikacjach na całym świecie, czy był to tylko błąd architektoniczny?
linuxunil
źródło
To pytanie jest podobne, ale nie dokładnie takie samo .. softwareengineering.stackexchange.com/questions/180012/…
Jon Raynor

Odpowiedzi:

7

Czy istnieje problem z wywoływaniem funkcji baz danych bezpośrednio przez aplikacje? Czy nie jest to uważane za złą praktykę?

Myślę, że jest. Umieszczasz wiedzę o wewnętrznych elementach bazy danych w usłudze aplikacji. Zmiana bazy danych w jakikolwiek sposób (zmiana silnika pamięci, a nawet zmiana nazwy pola lub utworzenie indeksu) może wymagać zmiany usługi aplikacji, co narusza SRP .

Jaki byłby model architektury mający zastosowanie do takiego projektu?

Zobacz komentarz poniżej.

Czy jest jakiś problem z mieszaniem zachowań w tej samej usłudze? Takie jak transakcje i spójność?

Nie wierzę, że jest problem techniczny, ale jest logiczny. Po prostu łączysz dwa podejścia w aplikacji, dzięki czemu jest niejasna, mniej ustrukturyzowana, trudna do dostosowania do zmian. Zobacz powyższe komentarze dotyczące naruszania SRP.

Czy w przypadku konserwacji enkapsulacja sprawia, że ​​programiście nie jest w stanie zmienić funkcji w bazie danych?

Jasne, że tak.

Jak tego uniknąć?

Umieść metody i funkcje bezpośrednio działające z bazą danych na osobnym poziomie abstrakcji (czy to warstwa DAO, czy prosty wzorzec repozytorium - zależy od złożoności aplikacji)

Czy ten scenariusz zdarza się w innych aplikacjach na całym świecie, czy był to tylko błąd architektoniczny?

Myślę, że w naszym świecie wszystko się dzieje;)

Vladislav Rastrusny
źródło
Jeśli dobrze rozumiem, może występować problem techniczny polegający na tym, że jeśli aktualizacje zachodzą w funkcjach / przechowywanych procesach, a także za pośrednictwem ORM, bardzo trudno jest uzasadnić stany danej transakcji. Chociaż aplikacja może działać w obecnym stanie, niewielka zmiana może kaskadowo doprowadzić do naprawdę poważnych problemów. Moje doświadczenie z Hibernacją polega na tym, że jeśli nie pozwolisz zarządzać całym zestawem tabel, z którymi współpracuje, będziesz mieć wiele irytujących problemów.
JimmyJames,
ładna i zwięzła odpowiedź. SRP było pierwszą rzeczą, która przyszła mi do głowy, kiedy po raz pierwszy spojrzałem na kod. Niektórzy współpracownicy twierdzą, że metoda ta nie narusza SRP, ponieważ wywołuje tylko funkcję bazy danych. Ale niektóre z tych funkcji wybierają, wstawiają i aktualizują. Czy to narusza SRP? (może to samo pytanie jest osobno omawiane osobno?)
linuxunil
1
+1 za tę linię Myślę, że w naszym świecie wszystko się dzieje;)
linuxunil,
@linuxunil SRP należy szanować na wszystkich poziomach architektury. W moim przypadku miałem na myśli SRP na poziomie usługi, a nie na poziomie metody. @ JimmyJames Yep. Większość ORM nie działa dobrze z procedurami przechowywanymi. Ale czasami przechowywany proces jest konieczny.
Vladislav Rastrusny
3

Zgodnie z tym, co powiedziałeś, istnieje warstwa usługi, więc wzór architektoniczny, który wydaje się odpowiedni, to architektura warstwowa. Dalsze informacje

Tak, zwykle złą praktyką jest wykonywanie bezpośrednich wywołań bazy danych na innej niż warstwa dostępu do danych, w ten sposób warstwa biznesowa ma dostęp tylko do abstrakcji bazy danych.

Jeśli chodzi o zachowania związane z mieszaniem, użycie pewnego wzorca projektowego jako wzorca DAO lub wzorca repozytorium może pomóc w delegowaniu tych obowiązków, poprawiając tym samym kod.

Jedną z zalet korzystania z wzorca projektowego i ORM jest czytelność kodu i hermetyzacja obowiązków, więc jeśli dostęp do bazy danych ulegnie zmianie, warstwa biznesowa nie powinna się wiele zmienić.

J. Pichardo
źródło
Nie jestem pewien, dlaczego zostało to odrzucone. Ta odpowiedź zaleca oddzielenie kodu, który dotyczy różnych problemów . Czuję się tu jak programista ... nie jestem pewien, co to jest ... Człowieku. Gdybym tylko mógł wymyślić nazwę. +1 BTW
Greg Burghardt
Czy to nie jest jedna z solidnych zasad?
J. Pichardo,
3
Nr „S” w postaci stałej jest S Ingle główny odpowiedzialny (SRP). Ale zalecana separacja obaw jest ważnym powodem oddzielenia logiki usługi od logiki dostępu do danych. Inna odpowiedź Vladislava wymienia dyrektora ds. Pojedynczej odpowiedzialności. Szczerze mówiąc, SRP i Separation of Concerns idą w parze, podobnie jak wino i ser.
Greg Burghardt,