Wpis z mikrobloga

W dwóch moich projektach w PHP opartych na Koseven wdrożyłem CQRS i to w dość prosty sposób w prostych CRUD-ach i jedyne co mogę powiedzieć to to że ma to same zalety, nie widzę wad (jak na rozmiar tych aplikacji) i zbytniej komplikacji kodu, tylko nie wiem czy to podejście które zastosowałem jest do końca prawidłowe. Tak jak przeglądałem niektóre tutoriale i kody na github temu poświęcone, realizacja w PHP wygląda tak. Każdy Command to właściwie tylko zwykła encja, gettery i settery i przyjmowanie danych np. z POST w konstruktorze, każdy Command Handler wykonuje jakieś operacje np. na ORM biorąc tylko dane z tej encji przez jej gettery i każdy Command ma swój osobny Command Handler. A Command Bus jest jeden i przy użyciu prostego mechanizmu refleksji przyjmując instancję Command odnajduje właściwy Command Handler.
Pierwszy taki przykład to jest tutaj:
https://mevelix.com/articles/laravel-cqrs-from-scratch,1

Na fajnie, spoko, tylko tak się zastanawiam czy w takich frameworkach jak CI, FuelPHP czy Koseven ma sens aż takie rozbijanie? Ja zrobiłem to tak. Każdy Command bierze tylko dane np. z $_POST i wykonuje jakieś operacje np. bazodanowe na ORM w swojej metodzie execute i mam tylko jeden Command Handler dla wszystkich Command który tylko w swojej handle obsługuje wyjątki, profilowanie i hooki np. success, failure, always itd. Command handler po prostu wywołuje metodę execute z komendy jako parametr swojej metody handle, przyjmując tylko instancje Command. Każde Query pobiera np. dane z bazy przez jakiś ORM i mam też tylko jeden główny Query Handler obsługujący wyjątki, profilowanie i hooki. Bardzo dobrze to mi się sprawdza. Żadnego overengineering.

Czy to są tylko szczegóły implementacyjne? W Laravelu inaczej się programuje niż w wymienionych tu frameworkach i pewnie to podejście rodem z tutoriali jest celowe. Ale nie chcę zbyt komplikować kodu i rozbijać na nie wiadomo ile klas. W każdym razie podejście jest bardzo ciekawe. Strasznie jestem ciekaw jak dużo programistów komplikuje sobie pracę, tworząc przeinżynierowane potworki tylko po to żeby się potem pochwalić w CV nowym fantastycznym słowem kluczowym? Co takiego konkretnego daje to że każdy Command ma być tylko zwykłą encją i ma mieć swój Command Handler to nie wiem. Nie można by tego zredukować tylko do jednej klasy Command?

#programista15k #cqrs #programowanie #php
  • 26
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@daro1:

return $command->execute();
CommandHandler by design jest asynchroniczny i nie zwraca żadnych danych.

Command nie powinien zawierać metody execute. To ma być obiekt będący intencją zmiany stanu aplikacji. Po prostu fajnie nazwana klasa z bezpośrednio zadeklarowanymi polami. Nic poza tym.
  • Odpowiedz
  • 0
@Pharos: Wiem że Command nie powinno zwracać żadnych danych. Ale na przykład jak jest potrzebne jakieś ID nowo utworzonego rekordu to nie wiem czy to nie jest odstępstwo od tej zasady. W moim rozwiązaniu jest jeden główny Command Handler który obsługuje wszystkie Command które są odrębnymi klasami do różnych zadań i warunkowo zwraca o ile to polecenie coś zwraca, bo jeżeli nie to to będzie NULL. Właśnie zrobiłem test na
  • Odpowiedz
dla mnie to rybka jak coś się nazywa


@daro1: Nie mów tego nigdzie na rekrutacji :)

Implementacja CQRS powinna zależeć od tego co dany framework
  • Odpowiedz
  • 0
@Pharos: A jak jest w bazie ID autoincrement to niby jak ma to wyglądać? Utworzyłem w bazie przy użyciu takiego Command co nic nie zwraca nowy rekord w bazie i mam je pobrać za pomocą Query jeśli potrzebuję. W porządku tylko że weźmy że ktoś inny w tej samej chwili utworzył tak nowy rekord. I co? Pobiorę ostatnio utworzony rekord (bez identyfikacji na podstawie innych danych wprowadzonych przeze mnie np.
  • Odpowiedz
A jak jest w bazie ID autoincrement to niby jak ma to wyglądać?


Na siłę możesz sobie w bazie danych utworzyć np. sekwencję i wykonywać request po następny numer. Wtedy masz identyfikator liczbowy zarezerwowany dla twojej transakcji i znasz go od razu, więc nie musisz nic zwracać z command handlera.

Biorąc jednak pod uwagę zdrowy rozsądek, to w 99% przypadków nie potrzebujesz CQRS tylko prostego CRUD-a. Na CQRS biznes musi być gotowy
  • Odpowiedz
@daro1: Śmiało zwracaj identyfikatory przy wykonywaniu komend. Nie warto komplikować sobie życia tylko po to żeby mieć pełną zgodność z definicją komendy sprzed 30 lat. Przy czym na zwracaniu identyfikatorów raczej bym poprzestał, bo całą resztę można już koszernie rozwiązać przez używanie query.

@Pharos To jest niestety plaga w tej branży. Widziałem wiele systemów na których ktoś ewidentnie budował sobie CV i używał narzędzi/wzorców/architektur które były tam kompletnie z
  • Odpowiedz