Jak poprawić ten kod?

0

Ostatnio chciałem napisać ubogą wersję OneDrive'a i popełniłem (to chyba dobre słowo) coś takiego: https://pastebin.com/D87SdhKP (GitHuba wolę nie pokazywać, bo w projekcie jeszcze dużo rzeczy do poprawienia). I tak: wydzieliłem z kontrolerów logikę (aplikacji) i powstała mi klasa mająca prawie 200 linii. Wiem, że kłóci się to z SOLID i nie wygląda dobrze. Chyba @somekind pisał kiedyś, że klasa powinna (zazwyczaj) mieścić się na jednym ekranie. Ładnie to brzmi, tylko jak to zrobić? Mam podzielić tę klasę na kilka innych, mających tylko po jedną metodę? Wiem też, że pobieranie UserManagera z IoC nie jest poprawne, ale jak inaczej, gdy jego jedyny konstruktor ma 9 (!) parametrów?

1

Dlaczego UserManager z IOC jest niepoprawne ?
Ja osobiście korzystam z Command Query Separation. Nie wiem czy jest to dobrze ale zazwyczaj udaje mi się robić małe klasy (mieści się na ekranie :D)
https://github.com/szydlaczek/Delegacje.

1

To że klasa ma 200 linii nie musi wcale łamać SOLID'a. Co do kodu to możesz wydzielić walidacje do innej klasy. Ja osobiście jestem zwolennikiem bez klamrowych jedno linijkowych ifów, ale to akurat nie każdy lubi.

0

@szydlak: Chodzi o to, że w IoC nie powinno się rejestrować zewnętrznych bibliotek, ale nie zawsze takie podejście jest pragmatyczne. https://4programmers.net/Forum/1539232 I o ile wiem, to CQRS używa się jedynie przy dużych projektach, tak?

1
nobody01 napisał(a):

I o ile wiem, to CQRS używa się jedynie przy dużych projektach, tak?

CQS nie CQRS

0

CQS spoko, ale musisz pamiętać że komenda nie powinna nic zwracać i będziesz musiał kombinować jak przekazać informacje do użytkownika czy logowanie się powiodło a jeśli nie to co poszło nie tak.

0
error91 napisał(a):

CQS spoko, ale musisz pamiętać że komenda nie powinna nic zwracać i będziesz musiał kombinować jak przekazać informacje do użytkownika czy logowanie się powiodło a jeśli nie to co poszło nie tak.

Ale można w Command dać jakieś pole np object (zwracane Id) oraz Succeeded typu bool. Bo inaczej faktycznie będzie to problem. Zazwyczaj potrzebujemy informację o powodzeniu lub nie.

0
szydlak napisał(a):

Ale można w Command dać jakieś pole np object (zwracane Id) oraz Succeeded typu bool. Bo inaczej faktycznie będzie to problem. Zazwyczaj potrzebujemy informację o powodzeniu lub nie.

Purystycznie podchodząc to własnie nie powinno. Jeśli nawet to nie rozwiązuje problemu wyświetlania użytkownikowi dlaczego coś poszło nie tak.

2
nobody01 napisał(a):

Ostatnio chciałem napisać ubogą wersję OneDrive'a i popełniłem (to chyba dobre słowo) coś takiego: https://pastebin.com/D87SdhKP (GitHuba wolę nie pokazywać, bo w projekcie jeszcze dużo rzeczy do poprawienia). I tak: wydzieliłem z kontrolerów logikę (aplikacji) i powstała mi klasa mająca prawie 200 linii. Wiem, że kłóci się to z SOLID i nie wygląda dobrze. Chyba @somekind pisał kiedyś, że klasa powinna (zazwyczaj) mieścić się na jednym ekranie. Ładnie to brzmi, tylko jak to zrobić? Mam podzielić tę klasę na kilka innych, mających tylko po jedną metodę?

Ano - każda publiczna metoda do oddzielnej klasy i problem długiej klasy i łamania SRP rozwiązany. Możliwe, że tak wydzielone klasy będą miały też mniej zależności.
Tak poza tym, to to Twoje UserService mogłoby się nazywać UserRegistrationDataValidator albo jakoś tak podobnie, w każdym razie bardziej odpowiadając celowi istnienia tej klasy.

0

Powiedzmy, że podzielę tę klasę na 3 mniejsze: jedna będzie odpowiedzialna za rejestrowanie (i potwierdzanie emaila, bo to podchodzi pod część procesu rejestracji), druga będzie odpowiedzialna za logowanie, a trzecia za operacje związane ze zmianą hasła. Wtedy do kontrolera będę musiał wstrzyknąć trzy zależności zamiast jednej. Trzy zależności to nie tak dużo, ale co, gdyby było ich (tych klas) więcej? Wtedy AuthService powinna pozostać i służyć jako fasada?

2

@nobody01: nie potrzeba fasady, do kontrolera można wstrzyknąć jedną zalężność - szynę, która wyśle obiekt do przetwarzania od odpowiedniej klasy np. na podstawie typu.
Przykład: https://devstyle.pl/2016/11/10/cqrsdi-implementacja-w-c-i-autofac/

2
somekind napisał(a):

@nobody01: nie potrzeba fasady, do kontrolera można wstrzyknąć jedną zalężność - szynę, która wyśle obiekt do przetwarzania od odpowiedniej klasy np. na podstawie typu.
Przykład: https://devstyle.pl/2016/11/10/cqrsdi-implementacja-w-c-i-autofac/

No ja dałem te implementacje w linku do github. Tam mam to zrobione. I korzystam tez z tego w pracy. Dobrze się sprawdza

0

@szydlak: A co przekazujesz do metod kontrolerów? Czy te Commands i Queries zastępują DTO?

0
nobody01 napisał(a):

@szydlak: A co przekazujesz do metod kontrolerów? Czy te Commands i Queries zastępują DTO?

Robię klasy Np LoginCommand
a ta zawiera w sobie cały obiekt np LoginViewModel.
już z hasłem i nazwą usera

0

Hmm... A co takie opakowywanie daje? Dlaczego nie można od razu zmapować przychodzących danych na LoginCommand?

0

Możesz np potrzebować wykorzystać ten Sam DTo, lub ViewModel przez różne CommandHandlery, A jak jest napisane na DevStyle jedna komenda to dokładnie jeden CommandHandler

0

@szydlak: A mógłbyś podać przykład takiej sytuacji? Żadna mi nie przychodzi do głowy. :(

1

Tworzenie obiektu i jego update. Np usera. Możesz wykorzystać ten sam Dto ale różne handlary. Dodatkowo np jak ktoś jest zalogowany to w klasie command możesz wysłać usera który wykonuje dana operacje a w Dto tego nie ma.
A tu masz moją implementację z jednego zadania rekrutacyjnego. https://4programmers.net/Forum/Ci.NET/313476-zadanie_rekrutacyjne?p=1507914#id1507914.
Teraz poprawiłem ten kod i wykorzystuje ten wzorzec Command Query.
https://github.com/szydlaczek/Company

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