Zanim przejdziemy do kodu warto rozwinąć skrót CQRS, Command Query Responsibility Segregation. Wzorzec opisał, przedstawił i prawdopodobnie wymyślił Greg Young.
Krótko mówiąc, celem tego wzorca jest rozdzielenie modelu służącego do zmiany stanu systemu od modelu służącego do odczytywania stanu systemu.
Wzorzec ten powstał prawdopodobnie na bazie pojęcia Command Query Separation. Pojęcie to z kolei wywodzi się z podstaw programowania obiektowego, mówi ono że metody obiektu można podzielić na dwa typy.
- Query - pozwalające uzyskać informację o obiekcie, odczytać go
- Commands - pozwalające wykonać operacje na obiekcie, zmodyfikować go
Trzymając się tej reguły nigdy nie powinniśmy tworzyć czegoś na wzór:
<?php
final class System
{
private $status = 0;
public function commandQuery() : int
{
$this->status = rand(0, 100);
return $this->status;
}
}
Jak widać, metoda commandQuery
służy zarówno do zmiany stanu obiektu System
jak i do jego pobrania. Odrobinę bardziej przewidywalna w skutkach implementacja tej samej klasy wyglądałaby tak:
<?php
final class System
{
private $status = 0;
public function command() : void
{
$this->status = rand(0, 100);
}
public function query() : int
{
return $this->status;
}
}
To przydługie wprowadzenie było niezbędne przed przejściem do tematu właściwego, CQRS. Myśląc o CQRS warto pamiętać o CQS tylko w skali bardziej globalnej, CQS odnosi się do obiektów, natomiast CQRS do systemu jako całości. CQS mówi, że metody obiektu dzielimy na te które odczytują i te które modyfikują. CQRS natomiast wyznacza sposób w jaki należy komunikować się z systemem, jak zmieniać jego stan oraz jak ten stan odczytywać.
Czym jednak jest wspominany co kilka zdań Stan Systemu?
Załóżmy, że pracujemy z systemem służącym do zarządzania użytkownikami. Stanem systemu jest więc ilość użytkowników czy szczegółowe dane konkretnego użytkownika.
W jaki sposób można zmienić Stan Systemu?
Zmiana stanu to na przykład utworzenie nowego użytkownika czy modyfikacja danych któregokolwiek z użytkowników.
W tym momencie powinniście się już domyślać, że CQRS to nic innego jak uporządkowany i jednolity sposób pozwalający zmieniać i odczytywać stan systemu. Zacznijmy więc od zmian.
Write Model
Zmiana stanu systemu zgodnie z wzorcem CQRS powinna być powodowana jedynie po zmianach w Write Modelu
. Postaram się wyjaśnić jak zbudować prosty system zbudowany z 3 prostych warstw wspartych przez implementację konkretnych narzędzi.
- Domain
- Application
- UserInterface
W tej części skupie się jedynie na zmianie stanu systemu, odczyt zostawię na koniec. Trzeba w końcu mieć z czego czytać.
User Interface
Każdy system posiada jakiś interfejs. Czasami jak w przypadku aplikacji desktopowych są to okienka, czasami może to być terminal a czasami protokół HTTP. Komendy mają swój początek właśnie w interfejsie użytkownika i reprezentują jego intencje względem systemu. System może posiadać wiele interfejsów użytkownika. Przykładowo do obsługi systemu zarządzania użytkownikami można stworzyć API RESTowe lub umożliwić dostęp bezpośrednio poprzez terminal. Obydwa interfejsy mogą pozwalać zrobić dokładnie to samo tylko przy użyciu innych narzędzi. W jednym wypadku konieczne będzie wysłanie Requestu HTTP zawierającego email oraz nazwę użytkownika: