Nazewnictwo dla klas usługowych.

0

Klasa usługowa zawiera metody, które pozwalają na operacje na obiektach domenowych. Zauważyłem, że nazywam te klasy zazwyczaj z postfiksem "Service", np. "MembersService", "AuthorizationService".

Co o tym sądzicie? Jak to wygląda u Was?

5

Staram się unikać tego sufiksu i nazywać jakoś konkretniej, w zależności od tego, co faktycznie robią.

7

Ciekawostka. Dawno temu trafiłem na artykuł/wpis na blogu (nie pamiętam dokładnie), gdzie ktoś sugerował unikania nazywania klas usługowych z końcówką -er Czyli handler, provider, adapter, manager, helper, itd. Pomijając oczywiście nazwy wzorców projektowych/architektonicznych gdzie mają one sens.

1
markone_dev napisał(a):

ktoś sugerował unikania nazywania klas usługowych z końcówką -er Czyli handler, provider, adapter, manager, helper, itd.

Ciekaw jestem czemu?

4
bakunet napisał(a):
markone_dev napisał(a):

ktoś sugerował unikania nazywania klas usługowych z końcówką -er Czyli handler, provider, adapter, manager, helper, itd.

Ciekaw jestem czemu?

Żeby nadawać klasom bardziej znaczace nazwy, wynikające z ich przeznaczenia czy sensu domenowego.

0

@markone_dev:

Rozumiem, ale na przykładzie takiego FileManagera, serwisu który odczytuje, usuwa, zapisuje, nadpisuje plik, sprawdza czy plik istnieje, jak można go nazwać inaczej? Ja mało widziałem, więc się zastanawiam.

0
Anatolijus napisał(a):

Klasa usługowa zawiera metody, które pozwalają na operacje na obiektach domenowych. Zauważyłem, że nazywam te klasy zazwyczaj z postfiksem "Service", np. "MembersService", "AuthorizationService".

Co o tym sądzicie? Jak to wygląda u Was?

Ogólnie wyglada to jak Spring sprzed 10 lat, ale nie wiem czy coś tam się zmieniło. BTW słyszałem kiedyś iż odpowiednikiem Springowo Javowego Service jest w C# Manager. Prawda to @somekind ?Tutoriale C#powe dalej tak doradzają ?

2
Anatolijus napisał(a):

Klasa usługowa zawiera metody, które pozwalają na operacje na obiektach domenowych. Zauważyłem, że nazywam te klasy zazwyczaj z postfiksem "Service", np. "MembersService", "AuthorizationService".

Co o tym sądzicie? Jak to wygląda u Was?

Sądzę że to jest bezsens. Staram się nie używać takich nazw. Nazywanie klasy UserService to jest symptom nieumiejętności znalezienia odpowiedniej nazwy.

W ogóle sam podział "klasa usługa", też nie ma specjalnego sensu dla mnie. Klasa to klasa, powinna robić jedną rzecz i nie łamać Separation of Concerns. Dopisanie prefixu "Service" nie zwiększy czytelności tej klasy.

bakunet napisał(a):

Rozumiem, ale na przykładzie takiego FileManagera, serwisu który odczytuje, usuwa, zapisuje, nadpisuje plik, sprawdza czy plik istnieje, jak można go nazwać inaczej? Ja mało widziałem, więc się zastanawiam.

No i tutaj jest serce problemu!

Dlatego że nazwa FileManager mówi zbyt mało, po samej nazwie ciężko się domyśleć co robi. Nazwa jest zbyt generyczna, i nie mówi co ta klasa robi tak na prawdę. Należałoby wejść do tej klasy i zobaczyć jaki jest sens jej istnienia w aplikacji, wtedy można by nazwać ją lepiej.

Myślę że nazwa FileManager została wymyślona przez kogoś kto chciał nadawać klasom zbyt ogólne nazwy - tak jakby miały być reużywalne w nieskończoność.

Równie dobrze mógłbyś nas zapytać: "Mam klasę dsfaffds, jak ją nazwać lepiej?" - odpowiedź brzmi: "musiałbym wejść do klasy i zobaczyć co robi".

@bakunet Pokaż klasę, to Ci zasugeruję kilka nazw, jak można by ją nazwać. W skrócie - zastanów się po co ta klasa zapisuje te pliki? Czy zapisuje je jako forma cache'? Nazwij ją Cache. Jeśli pliki są zapisywane jako backup, to nazwij klasę Backup. Jeśli pliki są jakimś dokumentem domenowym, to nazwij go Document albo Invoice. Wszystko zależy od tego do czego ta klasa jest używana, bo do czegoś na pewno jest. Natomiast jeśli faktycznie jest na tyle generyczna, że można jej użyć do wszystkiego, i nie ma faktycznie żadnego konkretnego użycia, to można ją nazwać po prostu File.

3
bakunet napisał(a):

@markone_dev:

Rozumiem, ale na przykładzie takiego FileManagera, serwisu który odczytuje, usuwa, zapisuje, nadpisuje plik, sprawdza czy plik istnieje, jak można go nazwać inaczej? Ja mało widziałem, więc się zastanawiam.

W .NET do tego służą klasy File, Directory, Path, itd. Da się napisać bibliotekę do IO beż FileManagera? Da :)

0
markone_dev napisał(a):
bakunet napisał(a):

@markone_dev:

Rozumiem, ale na przykładzie takiego FileManagera, serwisu który odczytuje, usuwa, zapisuje, nadpisuje plik, sprawdza czy plik istnieje, jak można go nazwać inaczej? Ja mało widziałem, więc się zastanawiam.

W .NET do tego służą klasy File, Directory, Path, itd. Da się napisać bibliotekę do IO beż FileManagera? Da :)

W Javie tez

0
markone_dev napisał(a):
bakunet napisał(a):

@markone_dev:

Rozumiem, ale na przykładzie takiego FileManagera, serwisu który odczytuje, usuwa, zapisuje, nadpisuje plik, sprawdza czy plik istnieje, jak można go nazwać inaczej? Ja mało widziałem, więc się zastanawiam.

W .NET do tego służą klasy File, Directory, Path, itd. Da się napisać bibliotekę do IO beż FileManagera?

Ale użycie tych klas też musisz mieć w jakiejś klasie którą musisz jakoś nazwać.

1
Anatolijus napisał(a):

Co o tym sądzicie? Jak to wygląda u Was?

Uważam, że to ok. Service jest na tyle pomocną i rozumianą nazwą, że polepsza czytelność. Manager, Helper takie nie są, bo nic nie mówią i mają wiele znaczeń

markone_dev napisał(a):

Ciekawostka. Dawno temu trafiłem na artykuł/wpis na blogu (nie pamiętam dokładnie), gdzie ktoś sugerował unikania nazywania klas usługowych z końcówką -er Czyli handler, provider, adapter, manager, helper, itd. Pomijając oczywiście nazwy wzorców projektowych/architektonicznych gdzie mają one sens.

Jeśli klasa zapewnia metody do których pasuje jeden czasownik to dodanie er i umieszczenie go w nazwie klasy poprawia czytelność. Zresztą po to są nazwy, żeby użytkownik danego API wiedział co dane coś robi. Np. Base64Encoder albo Base64EncoderDecoder to według mnie dobre nazwy. Taki zabieg pasuje IMO do klas, które są zwykłymi funkcjami tj. trzymają mało stanu (lub w ogóle) i są tylko po to, bo trzeba bawić się w obiekty w językach OOP, żeby było konsystentnie

Problem zaczyna się, gdy czasownik jest zbyt ogólny np. help, manage bo to wtedy jest to zbyt ogólne.

bakunet napisał(a):

Rozumiem, ale na przykładzie takiego FileManagera, serwisu który odczytuje, usuwa, zapisuje, nadpisuje plik, sprawdza czy plik istnieje, jak można go nazwać inaczej? Ja mało widziałem, więc się zastanawiam.

Ja bym dał FileSystem. Oczywiście większość API tego nie robi, bo są zaprojektowane pod przypadek najbardziej ogólny tj. uderzają do lokalnego file systemu i ich funkcjonalność rozbita jest na funkcje, które są prostsze do wywołania np. os.Rename(from, to) niż zabawa w obiektowość

Riddle napisał(a):

Ale użycie tych klas też musisz mieć w jakiejś klasie którą musisz jakoś nazwać.

Możesz użyć zwykłych funkcji. Twój kod jest mniej rozszerzalny i przyspawany do lokalnego file systemu, ale jest prostszy. Jak potrzebujesz obiektowej abstrakcji to też możesz ją zbudować samemu zamiast polegać na takiej z biblioteki standardowej

0
slsy napisał(a):
Anatolijus napisał(a):

Co o tym sądzicie? Jak to wygląda u Was?

Uważam, że to ok. Service jest na tyle pomocną i rozumianą nazwą, że polepsza czytelność. Manager, Helper takie nie są, bo nic nie mówią i mają wiele znaczeń

A "Service" mówi? :D To jest buzzword, szum informacyjny. Nie dostajesz żadnych nowych informacji widząc dodatkowo słowo "Service".

markone_dev napisał(a):

Ciekawostka. Dawno temu trafiłem na artykuł/wpis na blogu (nie pamiętam dokładnie), gdzie ktoś sugerował unikania nazywania klas usługowych z końcówką -er Czyli handler, provider, adapter, manager, helper, itd. Pomijając oczywiście nazwy wzorców projektowych/architektonicznych gdzie mają one sens.

Jeśli klasa zapewnia metody do których pasuje jeden czasownik to dodanie er i umieszczenie go w nazwie klasy poprawia czytelność. Zresztą po to są nazwy, żeby użytkownik danego API wiedział co dane coś robi. Np. Base64Encoder albo Base64EncoderDecoder to według mnie dobre nazwy. Taki zabieg pasuje IMO do klas, które są zwykłymi funkcjami tj. trzymają mało stanu (lub w ogóle) i są tylko po to, bo trzeba bawić się w obiekty w językach OOP, żeby było konsystentnie

Słaby przykład, bo po co do tego dwie klasy? Czemu nie Base64.encode() i Base64.decode()?

bakunet napisał(a):

Rozumiem, ale na przykładzie takiego FileManagera, serwisu który odczytuje, usuwa, zapisuje, nadpisuje plik, sprawdza czy plik istnieje, jak można go nazwać inaczej? Ja mało widziałem, więc się zastanawiam.

Ja bym dał FileSystem. Oczywiście większość API tego nie robi, bo są zaprojektowane pod przypadek najbardziej ogólny tj. uderzają do lokalnego file systemu i ich funkcjonalność rozbita jest na funkcje, które są prostsze do wywołania np. os.Rename(from, to) niż zabawa w obiektowość

Ten sam problem co z FileManager, czyli zbyt generyczna nazwa, która w żaden sposób nie mówi co ta klasa robi.

Riddle napisał(a):

Ale użycie tych klas też musisz mieć w jakiejś klasie którą musisz jakoś nazwać.

Możesz użyć zwykłych funkcji. Twój kod jest mniej rozszerzalny i przyspawany do lokalnego file systemu, ale jest prostszy. Jak potrzebujesz obiektowej abstrakcji to też możesz ją zbudować samemu zamiast polegać na takiej z biblioteki standardowej

Czyli Twoja rada to:

  • Albo - zamiast używać FileManager, to usuń ją i używaj funkcji
  • Albo - zbuduj abstrakcję, i na niej polegaj i nazwij ją "jakoś".

No faktycznie takie ma opcje: usuń albo nazwij ją "jakoś".

Całkowicie ignorujesz to, że ta klasa FileManager czy FileSystem w tej aplikacji jest dodana po coś. Istnieje jakiś powód, czemu jest w tej klasie i tym powodem nie jest tylko "operacje na plikach", tylko jakaś potrzeba użytkownika - cache, backup, edycja, serializacja, etc. I ta klasa w której przebywają te operacje powinna być właśnie nazwana tym celem, a nie tylko tym że "opertuje na plikach".

0
Riddle napisał(a):

A "Service" mówi? :D To jest buzzword, szum informacyjny. Nie dostajesz żadnych nowych informacji widząc dodatkowo słowo "Service".

Nic nie mówi, ale ta nazwa jest po prostu w użyciu i dlatego jest pomocna.

Słaby przykład, bo po co do tego dwie klasy? Czemu nie Base64.encode() i Base64.decode()?

SRP

Ten sam problem co z FileManager, czyli zbyt generyczna nazwa, która w żaden sposób nie mówi co ta klasa robi.

Dalej FileSystem jest znanym terminem w branży i dlatego użycie tej nazwy jest pomocne. Jak dla mnie Javowy https://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html jest całkiem dobrze zaprojektowany i twórcy uznali, że ta nazwa ma sens.

Całkowicie ignorujesz to, że ta klasa FileManager czy FileSystem w tej aplikacji jest dodana po coś. Istnieje jakiś powód, czemu jest w tej klasie i tym powodem nie jest tylko "operacje na plikach", tylko jakaś potrzeba użytkownika - cache, backup, edycja, serializacja, etc. I ta klasa w której przebywają te operacje powinna być właśnie nazwana tym celem, a nie tylko tym że "opertuje na plikach".

Jakbyś inaczej to nazwał takie "coś" (tj. FileManager, FileSystem)? IMO sens tej nazwy wynika z tego, że wszystkie te metody operują na pewnym określonym file systemie. Takim file systemem mógłby być lokalny file system, ale też np. adapter do cloud storage

0

W c# zdarzają mi się kolizje namespace oraz klas gdy staram się stosować krótsze nazwy.
Ostatnio w solucji miałem projekt: Example.Boards, a w nim public sealed class BoardsFacade(Boards boards, ...){}

Pomijając tę kolizję nazw. Patrząc teraz na ten kod myślę, ze powinienem rozbić tę klasę na 2: Boards i BoardsMembership.
Kusi mnie, żeby dodać Manager do tej drugiej. Co do Boards to ta nazwa mi się nie podoba.

public sealed class Boards(...) {
  public Either<IError, Board> Add(...) {} //mapowanie DTO, zapis do bazy
  public Either<IError, Unit> Remove(...) {} // usunięcie z bazy
  public Either<IError, Unit> AddMember(BoardId boardId, UserId userId) {}
  public Either<IError, Unit> RemoveMember(BoardId boardId, UserId memberId) {}
}
3
markone_dev napisał(a):
bakunet napisał(a):
markone_dev napisał(a):

ktoś sugerował unikania nazywania klas usługowych z końcówką -er Czyli handler, provider, adapter, manager, helper, itd.

Ciekaw jestem czemu?

Żeby nadawać klasom bardziej znaczace nazwy, wynikające z ich przeznaczenia czy sensu domenowego.

CreateInvoiceHandler czy CustomerDataProvider to jak najbardziej nazwy wynikające z przeznaczenia czy domeny.
Co do helper czy manager, bo takie nazwy sugerują, że klasa ma potencjalnie nieskończoną odpowiedzialność, więc każdy dopisuje tam sobie metody, które mu pasują.
Chyba z raz widziałem Managera, który miał sens - klasa ta była odpowiedzialna za tworzenie/usuwanie serwisów ServiceFabricowych.

KamilAdam napisał(a):

Ogólnie wyglada to jak Spring sprzed 10 lat, ale nie wiem czy coś tam się zmieniło. BTW słyszałem kiedyś iż odpowiednikiem Springowo Javowego Service jest w C# Manager. Prawda to @somekind ?Tutoriale C#powe dalej tak doradzają ?

Nie widziałem nigdy tutoriala, który by tak doradzał, w swojej karierze zawodowej widziałem też setki Service, i może z kilka Managerów. Ale może po prostu nie trafiam na projekty tworzone przez takich tytanów nazewnictwa, nie wiem.

bakunet napisał(a):

@markone_dev:

Rozumiem, ale na przykładzie takiego FileManagera, serwisu który odczytuje, usuwa, zapisuje, nadpisuje plik, sprawdza czy plik istnieje, jak można go nazwać inaczej? Ja mało widziałem, więc się zastanawiam.

FileSystem

slsy napisał(a):

Nic nie mówi, ale ta nazwa jest po prostu w użyciu i dlatego jest pomocna.

Nie jest, bo tak samo jak Helper czy Manager na ogół nie opisuje do czego służy, za to jest workiem na wszystko.

Słaby przykład, bo po co do tego dwie klasy? Czemu nie Base64.encode() i Base64.decode()?

SRP

Jeśli klasa odpowiada za obsługę Base64, to ciężko tu o łamanie SRP.

Anatolijus napisał(a):

Kusi mnie, żeby dodać Manager do tej drugiej.

Idź się wyspowiadaj z tego pomysłu.

1
slsy napisał(a):

Słaby przykład, bo po co do tego dwie klasy? Czemu nie Base64.encode() i Base64.decode()?

SRP

A z jakiej racji? Ty wiesz o chodzi w SRP?

Jedna klasa odpowiada tekst w base64, i tą klasą mogłoby być Base64. To że ona umie jednocześnie zakodować i odkodować to nie znaczy że łamie SRP (chociażby dlatego że i tak gdybyś chciał je zmienić to musiałbyś zmienić obie).

Gdyby to co mówisz było prawdą, i każda funkcja klasy jest osobną odpowiedzialnością, to w klasie File albo Database nie mógłbyś mieć File.read() i File.write(), bo przecież odczytywanie i zapisywanie byłby osobnymi odpowiedzialnościami. Jak miałbyś transaction.commit(), to nie mógłbyś mieć już transaction.rollback(). Tak na prawdę każda klasa musiałaby mieć tylko jedną publiczną metodę, bo gdyby miała dwie to łamałaby SRP. Nie byłoby sensu używać obiektów, bo każdą klasę z pojedynczą metodą możnaby zastąpić jedną funkcją. Jasno widać że takie rozumienie SRP jest bez sensu.

Jak więc rozumieć SRP i czemu ma służyć?

SRP ma pomóc nam minimalizować skutki niepożądanej zmiany zachowania przy edycji kawałka kodu - np zmieniamy nazwę pola w widoku, i nagle integracja z paypalem przestaje działać. Takie zjawisko jest bardzo popularne w projektach gdzie SRP się nie stosuje. W jaki sposób więc SRP chroni nas przed takimi nieoczekiwanymi zmianami? "R" w SRP to nie jest to co klasa robi, tylko jej powód do zmiany. "Zasada pojedynczej odpowiedzialności" oznacza "Zasada pojedynczego powodu do zmiany". Dlatego moim zdaniem klasa Base64 która ma metody zarówno encode() jak i decode() nie łamie SRP. Łamałaby ją gdyby miała metody np zarówno Base64.encode() jak i Base64.sendHttpAuthorizationHeader(). Nie chodzi też o ilość metod, bo jedna klasa może mieć 10 bardzo ze sobą spójnych metod, a z kolei inna klasa może mieć dwie zupełnie odstające.

slsy napisał(a):

Całkowicie ignorujesz to, że ta klasa FileManager czy FileSystem w tej aplikacji jest dodana po coś. Istnieje jakiś powód, czemu jest w tej klasie i tym powodem nie jest tylko "operacje na plikach", tylko jakaś potrzeba użytkownika - cache, backup, edycja, serializacja, etc. I ta klasa w której przebywają te operacje powinna być właśnie nazwana tym celem, a nie tylko tym że "opertuje na plikach".

Jakbyś inaczej to nazwał takie "coś" (tj. FileManager, FileSystem)? IMO sens tej nazwy wynika z tego, że wszystkie te metody operują na pewnym określonym file systemie. Takim file systemem mógłby być lokalny file system, ale też np. adapter do cloud storage

Jeśli klasa jest generyczna - tak że nie ma tam absolutnie nic z logiki biznesowej, ale nic, żadnej stałej, żadnej zmienne, żadnej wartości z domeny, to w takim razie, jeśli ta klasa faktycznie jest generyczna, to powinna się nazywać File. Nie ma po co dodawać Manager albo System, co niby tym zyskasz?

Natomiast jeśli ma coś z domeny (jakąś ścieżkę, jakąś wartośc, cokolwiek) to należałoby nazwać tą klasę tym co robi (np Cache, Backup, Document, etc.)

1

Szczerze mówiąc ja przyzwyczaiłem się do postfixu Service bo to się wszędzie widzi w projektach i od razu wiadomo, że zwykle taka klasa zawiera jakąś procedurę biznesową, która spina inne elementy w całość. Zresztą nawet sama nazwa service layer w architekturze warstwowej wskazuje na to, że tam są serwisy więc to jest imho naturalne.

1
lukascode napisał(a):

Szczerze mówiąc ja przyzwyczaiłem się do postfixu Service bo to się wszędzie widzi w projektach i od razu wiadomo, że zwykle taka klasa zawiera jakąś procedurę biznesową, która spina inne elementy w całość.

I zwykle błędnie - często łączone są elementy, które nie mają ze sobą nic wspólnego poza tym, że łączy je jakieś słowo kluczowe.

Zresztą nawet sama nazwa service layer w architekturze warstwowej wskazuje na to, że tam są serwisy więc to jest imho naturalne.

No, to może nie stosować architektury, która każe robić dziwne rzeczy.

0
Riddle napisał(a):

Jeśli klasa jest generyczna - tak że nie ma tam absolutnie nic z logiki biznesowej, ale nic, żadnej stałej, żadnej zmienne, żadnej wartości z domeny, to w takim razie, jeśli ta klasa faktycznie jest generyczna, to powinna się nazywać File. Nie ma po co dodawać Manager albo System, co niby tym zyskasz?

Na przykładzie javowego FileSystem mamy File, które pozwala na operacja na jednym pliku i FileSystem

5

Używam XYZService i nie mam z tym problemu. IMO dość sensowny sposób wyróżnienia gdzie szukać API/Fasady w module.

1
Riddle napisał(a):
markone_dev napisał(a):
bakunet napisał(a):

@markone_dev:

Rozumiem, ale na przykładzie takiego FileManagera, serwisu który odczytuje, usuwa, zapisuje, nadpisuje plik, sprawdza czy plik istnieje, jak można go nazwać inaczej? Ja mało widziałem, więc się zastanawiam.

W .NET do tego służą klasy File, Directory, Path, itd. Da się napisać bibliotekę do IO beż FileManagera?

Ale użycie tych klas też musisz mieć w jakiejś klasie którą musisz jakoś nazwać.

No i tu wchodzi Service albo Handler jako nazwy klas reprezentujących styl architektoniczny. Klasy typu ApplicationService, DomainService, CommandHandler, QueryHandler mają swój odpowiednik w stylach architektonicznych i jak są umieszczone w odpowiednich miejscach zgodnie ze stylem architektonicznym, to takie nazwy mają sens i są wręcz pożądane.

Problem zaczyna się gdy z braku laki i chęci, ktoś zaczyna wszystkie klasy nazywać service, manager, helper czy provider

0
markone_dev napisał(a):

Problem zaczyna się gdy z braku laki i chęci, ktoś zaczyna wszystkie klasy nazywać service, manager, helper czy provider

Zgadzam się, co do tego — faktycznie to jest lipa. Jak ktoś wsadza te nazwy wszędzie, to faktycznie jest to słabe.

markone_dev napisał(a):

No i tu wchodzi Service albo Handler jako nazwy klas reprezentujących styl architektoniczny. Klasy typu ApplicationService, DomainService, CommandHandler, QueryHandler mają swój odpowiednik w stylach architektonicznych i jak są umieszczone w odpowiednich miejscach zgodnie ze stylem architektonicznym, to takie nazwy mają sens i są wręcz pożądane.

Argument z tym, żeby nazywać klasy od "stylu architektonicznego" nie koniecznie musi być zły (tutaj plus), ale nie koniecznie musi też być dobry. Co stoi na przeszkodzie klasę ApplicationService nazwać po prostu Application?

Chyba to co chcę powiedzieć to to, że jest kilka ograniczonych przypadków w których użycie słów "service" i "handler" jest uzasadnione, więc tutaj @markone_dev się zgadzam; ale niemniej w znacznej większości są one nagminnie nadużywane, i słowa "service" albo "handler" są dowalane do klasy w sumie nie wiadomo po co - chyba żeby się przystosować do jakiegoś bardziej "industrialnego" stylu czy coś. Ktoś może pomyśleć że jak jego aplikacja składa się z service'ów, handlerów i providerów to będzie "bardziej pro". A jak mamy krótkie, proste nazwy takie jak np Application albo File, to że wyglada "amatorsko". Tymczasem dodając taki suffix zyskujemy... no właśnie, w sumie nic. I efekt jest w zasadzie odwrotny.

1
markone_dev napisał(a):

No i tu wchodzi Service albo Handler jako nazwy klas reprezentujących styl architektoniczny. Klasy typu ApplicationService, DomainService, CommandHandler, QueryHandler mają swój odpowiednik w stylach architektonicznych i jak są umieszczone w odpowiednich miejscach zgodnie ze stylem architektonicznym, to takie nazwy mają sens i są wręcz pożądane.

Jaki styl architektoniczny wymaga nazywania klas AbcService albo XyzHandler?

0
somekind napisał(a):
markone_dev napisał(a):

No i tu wchodzi Service albo Handler jako nazwy klas reprezentujących styl architektoniczny. Klasy typu ApplicationService, DomainService, CommandHandler, QueryHandler mają swój odpowiednik w stylach architektonicznych i jak są umieszczone w odpowiednich miejscach zgodnie ze stylem architektonicznym, to takie nazwy mają sens i są wręcz pożądane.

Jaki styl architektoniczny wymaga nazywania klas AbcService albo XyzHandler?

A gdzie napisałem, że wymaga? Napisałem że klasy typu ApplicationService, DomainService czy CommandHandler mają swoje odpowiedniki w stylach architektonicznych jak DDD, CQRS czy Onion i ogólnie przyjęło się, że klasy nazywamy w ten sposób czyli OrderService, PlaceOrderHandler, FindUserOrdersHandler, itd. Tak samo jak swoje miejsce mają klasy typu Controller w MVC czy Presenter w MVP i jakoś nikt się o to nie pruje.

Oczywiście nikt ci nie broni nazywać sobie tych klas inaczej. Niemniej utarł się pewien schemat i o nim piszę.

0
markone_dev napisał(a):

A gdzie napisałem, że wymaga? Napisałem że klasy typu ApplicationService, DomainService czy CommandHandler mają swoje odpowiedniki w stylach architektonicznych jak DDD, CQRS czy Onion i ogólnie przyjęło się, że klasy nazywamy w ten sposób czyli OrderService, PlaceOrderHandler, FindUserOrdersHandler, itd. Tak samo jak swoje miejsce mają klasy typu Controller w MVC czy Presenter w MVP i jakoś nikt się o to nie pruje.

Oczywiście nikt ci nie broni nazywać sobie tych klas inaczej. Niemniej utarł się pewien schemat i o nim piszę.

Tylko dla mnie określenia "przyjęło się" oraz "utarł się schemat" znaczą praktycznie to samo co "nie ma powodu żeby tak robić"? (oprócz tego że inni tak robią, też bez powodu, ad. infinitum?)

2
Riddle napisał(a):
markone_dev napisał(a):

A gdzie napisałem, że wymaga? Napisałem że klasy typu ApplicationService, DomainService czy CommandHandler mają swoje odpowiedniki w stylach architektonicznych jak DDD, CQRS czy Onion i ogólnie przyjęło się, że klasy nazywamy w ten sposób czyli OrderService, PlaceOrderHandler, FindUserOrdersHandler, itd. Tak samo jak swoje miejsce mają klasy typu Controller w MVC czy Presenter w MVP i jakoś nikt się o to nie pruje.

Oczywiście nikt ci nie broni nazywać sobie tych klas inaczej. Niemniej utarł się pewien schemat i o nim piszę.

Tylko dla mnie określenia "przyjęło się" oraz "utarł się schemat" znaczą praktycznie to samo co "nie ma powodu żeby tak robić"? (oprócz tego że inni tak robią, też bez powodu, ad. infinitum?)

Nie chce mi się wchodzić w filozoficzne dyskusje. Chcesz robić inaczej to rób. Przecież nikt ci nie zabroni w architekturze MVC zamiast EmployeeController nazwać klasę EmployeeHttpRequestProcessor bo twoim zdaniem ma więcej sensu. Na szczęście większość programistów idzie utartym schematem przez co nie muszę się zastanawiać nad tym co autor chciał przez to wyrazić? Swoje ego, swój indywidualizm czy jeszcze coś innego.

0
markone_dev napisał(a):

Nie chce mi się wchodzić w filozoficzne dyskusje. Chcesz robić inaczej to rób. Przecież nikt ci nie zabroni w architekturze MVC zamiast EmployeeController nazwać klasę EmployeeHttpRequestProcessor bo twoim zdaniem ma więcej sensu. Na szczęście większość programistów idzie utartym schematem przez co nie muszę się zastanawiać nad tym co autor chciał przez to wyrazić? Swoje ego, swój indywidualizm czy jeszcze coś innego.

Pojęcie "architekturze MVC" to jakiś żart (bo rozumiem że odnosisz się do takiego "mvc" jaki jest np prezentowany w domyślnych scaffoldach frameworków Spring, Laravel, Rails czy Django?).

Frameworki te narzucają warstwową strukturę projektu, często dodając dodatkowe (np warstwa controllerów, warstwa modelów, warstwa widoków, warstwa middleware'ów, warstwa kolejek, etc.) - i taka warstwowość to jest wymysł autorów tych frameworków, a nie faktyczna cecha wzorca MVC - przez to wielu ludzi myśli teraz że MVC == "warstwy". W MVC żadnych warstw nie było. Argumenty czemu takie warstwowanie jest słabe można mnożyć. Jednym z nich jest to, że nawet sami użytkownicy tych frameworków zaczynają zauważać że takie warstwy dodają zbyt silne powiązania i starają się to obchodzić, proponując np. vertical slicing - według niektórych super pomysł. Tylko że pomysł z vertical slicing tylko dlatego stał się konieczny, żeby obejśc warstwy które są sztucznie nałożone przez framework - tych warstw w ogóle nie powinno być.

Autor MVC, Trygve Reenskaug, zapoczątkował wzorzec w latach ~1970-którymś. Nie było w nim mowy o żadnych warstwach, ani o niczym takim.

Więc, odpowiadając @markone_dev na Twój argument:

markone_dev napisał(a):

Przecież nikt ci nie zabroni w architekturze MVC zamiast EmployeeController nazwać klasę EmployeeHttpRequestProcessor bo twoim zdaniem ma więcej sensu.

Dodając takie klasy jak EmployeeController, to co tak na prawdę robisz, to dopasowujesz się do schematu nałożonego przez framework (który próbuje Cię przekonać że ten schemat to MVC).

markone_dev napisał(a):

Na szczęście większość programistów idzie utartym schematem przez co nie muszę się zastanawiać nad tym co autor chciał przez to wyrazić?

To że to jest "czytelniejsze" albo to że "nie musisz się zastanawiać nad tym co autor chciał przez to wyrazić", to tak na prawdę chodzi o to żebyś wiedział do której szufladki frameworkowej autor feature chciał go wsadzić. Tylko że to nie byłoby konieczne, gdyby nie te szufladki frameworka.

0
Riddle napisał(a):
markone_dev napisał(a):

Nie chce mi się wchodzić w filozoficzne dyskusje. Chcesz robić inaczej to rób. Przecież nikt ci nie zabroni w architekturze MVC zamiast EmployeeController nazwać klasę EmployeeHttpRequestProcessor bo twoim zdaniem ma więcej sensu. Na szczęście większość programistów idzie utartym schematem przez co nie muszę się zastanawiać nad tym co autor chciał przez to wyrazić? Swoje ego, swój indywidualizm czy jeszcze coś innego.

Pojęcie "architekturze MVC" to jakiś żart (bo rozumiem że odnosisz się do takiego "mvc" jaki jest np prezentowany w domyślnych scaffoldach frameworków Spring, Laravel, Rails czy Django?).

Mówiłem o przyjętej konwencji nazewniczej na przykładzie nazw kontrolerów architekturze MVC. Nie pisałem nic o warstwach ani niczym takim. Zamiast MVC wstaw sobie MVP. Nieważne. Przyjęło się nazewnictwo Controller, Presenter i tego się trzymajmy.

A jak chcesz uprawiać filozofię to nie że mną bo ja już swoje powiedziałem i nie mam nic więcej do dodania w tym temacie

0
markone_dev napisał(a):

Mówiłem o przyjętej konwencji nazewniczej na przykładzie nazw kontrolerów architekturze MVC.

Ale ta konwencja nie przynosi nic dobrego. Tylko zachęca jeszcze bardziej do dopasowania swojego projektu pod framework.

Okej, może powiem inaczej:

Jeśli chcesz się dopasować pod framework, i pisać wszystko przez pryzmat tego frameworka (np Spring, Rails, Laravel), to nazywaj klasy tak jak dokumentacja tego frameworka mówi: dodaj Controller, widok, model ORM'owy etc. (tylko nie ubieraj tego w jakieś wzniosłe terminy jak architektura czy MVC).

Natomiast jeśli chcesz po prostu stworzyć aplikację, a framework trzymać "at-arms-length", czyli innymi słowy mieć loose-coupling z tym frameworkiem, to warto nie stosować tych konwencji. I nie mam na myśli tutaj żeby teraz zrobić rename klas UsersController na Users, nie o to chodzi - ja mówię o tym, że czysto zrobiona aplikacja w ogóle nie powinna mieć struktury takiej jaka wychodzi jak odpalisz scaffold frameworka. I w takiej aplikacji nie ma sensu dodawać zarostków Service, Handler, etc, bo wszystko jest pogrupowane po odpowiedzialnościach, i można łatwo się rozeznać co jest gdzie i do czego służy po odpowiednich nazwach.

Większość programistów nie wyobraża sobie aplikacji Laravel która nie miałaby w roocie projektu katalogów app/, bootstrap/, config/, database/, routes/ czy storage/. Tylko że sama taka struktura narzucona przez framework ogranicza zaprojektowanie dobrej architektury takiej aplikacji, i praktycznie przywiązuje nas do schematu narzuconego przez framework - do tego stopnia że nie wyobrażamy sobie programować bez niego (co moim skromnym zdaniem jest szalone trochę). A to totalnie można łatwo zrobić - jeśli się zbuduje odpowiednią abstrakcję.

1 użytkowników online, w tym zalogowanych: 0, gości: 1