Przejdź do głównej treści
Grafika przedstawia ukryty obrazek

CQRS i Event Sourcing w PHP

Zdjecie zwiazane z CQRS i Event Sourcing w PHP

Command Query Responsibility Segregation (CQRS) oraz Event Sourcing to wzorce architektoniczne, które umożliwiają efektywne zarządzanie danymi i zwiększają skalowalność aplikacji. W tym artykule przedstawimy ich podstawowe założenia oraz sposób implementacji w PHP.

CQRS – Podział odpowiedzialności

CQRS polega na rozdzieleniu operacji odczytu (Query) i zapisu (Command). Dzięki temu można niezależnie skalować obie części oraz stosować inne modele danych dla odczytu i zapisu.

Przykład CQRS w PHP

Komendy (Commands) i ich obsługa:

class CreateUserCommand {
    public function __construct(
        public string $userId,
        public string $name,
        public string $email
    ) {}
}

class CreateUserHandler {
    public function handle(CreateUserCommand $command) {
        // Tutaj zapisujemy dane użytkownika
        echo "Użytkownik {$command->name} został utworzony.";
    }
}

Zapytania (Queries) i ich obsługa:

class GetUserQuery {
    public function __construct(public string $userId) {}
}

class GetUserHandler {
    private array $users = [
        '1' => ['name' => 'Jan Kowalski', 'email' => 'jan@example.com']
    ];

    public function handle(GetUserQuery $query) {
        return $this->users[$query->userId] ?? null;
    }
}

Event Sourcing – Śledzenie zmian w systemie

Event Sourcing to technika, w której zamiast zapisywać aktualny stan obiektu, przechowujemy sekwencję zdarzeń, które doprowadziły do tego stanu.

Przykład Event Sourcing w PHP

Definicja zdarzeń:

interface Event {}

class UserCreatedEvent implements Event {
    public function __construct(
        public string $userId,
        public string $name,
        public string $email
    ) {}
}

Rejestrowanie zdarzeń:

class EventStore {
    private array $events = [];

    public function append(Event $event) {
        $this->events[] = $event;
    }

    public function getEvents(): array {
        return $this->events;
    }
}

Odtwarzanie stanu obiektu z historii zdarzeń:

class User {
    public function __construct(
        private string $userId,
        private string $name,
        private string $email
    ) {}

    public static function reconstitute(array $events): ?self {
        $user = null;
        foreach ($events as $event) {
            if ($event instanceof UserCreatedEvent) {
                $user = new self($event->userId, $event->name, $event->email);
            }
        }
        return $user;
    }
}

Najprostsza implementacja Event Sourcingu w PHP

$events = [
    'init'      => function($a, &$r) {$r  = $a;},
    'add'       => function($a, &$r) {$r += $a;},
    'subtract'  => function($a, &$r) {$r -= $a;},
];
$store = [
    ['init', 0],
    ['add', 1],
    ['add', 2],
    ['subtract', 5],
    //...
];
file_put_contents('store.json', json_encode($store));

$store = json_decode(file_get_contents('store.json'), true);
$result = null;
foreach ($store as $array)
{
    $name = $array[0];
    $value = $array[1];    
    $callback = $events[$name];
    $params = [$value, &$result];
    call_user_func_array($callback, $params);    
}
var_dump($result);

Zalety i wady CQRS oraz Event Sourcing

Zalety:

  • Skalowalność – Możliwość osobnego skalowania operacji zapisu i odczytu.
  • Lepsza organizacja kodu – Jasny podział na odpowiedzialności.
  • Historia zmian – Event Sourcing pozwala na dokładne śledzenie zmian w systemie.
  • Łatwiejsza obsługa złożonych domen biznesowych – Szczególnie w aplikacjach wymagających wersjonowania danych.

Wady:

  • Złożoność – Wprowadzenie CQRS i Event Sourcingu wymaga dodatkowego kodu i narzędzi do obsługi zdarzeń.
  • Koszty przechowywania danych – Event Sourcing wymaga przechowywania pełnej historii zmian.
  • Trudniejsza nauka i wdrożenie – Wymaga zmiany sposobu myślenia o danych w systemie.

Kiedy stosować CQRS i Event Sourcing?

Kiedy są wskazane?

  • W systemach o wysokiej skalowalności, gdzie odczyt i zapis wymagają niezależnej optymalizacji.
  • Gdy potrzebne jest pełne śledzenie zmian w systemie (np. aplikacje finansowe, systemy audytowe).
  • W złożonych domenach biznesowych, gdzie logika aplikacji jest trudna do odwzorowania w klasycznych modelach relacyjnych.

Kiedy mogą prowadzić do overengineeringu?

  • W prostych aplikacjach CRUD, gdzie klasyczna baza danych wystarcza do obsługi operacji.
  • Gdy złożoność systemu nie uzasadnia dodatkowej warstwy abstrakcji.
  • Jeśli głównym celem jest szybkie dostarczenie rozwiązania, a nie długoterminowa skalowalność.

Podsumowanie

CQRS i Event Sourcing to potężne wzorce architektoniczne, które pomagają w budowaniu skalowalnych i wydajnych systemów. Dzięki CQRS możemy oddzielić operacje odczytu od zapisu, a Event Sourcing umożliwia pełne śledzenie zmian w systemie. W PHP można je zaimplementować za pomocą prostych klas i interfejsów, jak pokazano w powyższych przykładach. Należy jednak rozważyć ich zastosowanie, aby uniknąć nadmiernej komplikacji w projektach, które ich nie wymagają.

13 lutego 2025 23

Kategorie

programowanie

Dziękujemy!
()

Powiązane wpisy

Zdjecie zwiazane z Automatyczny motyw Bootstrap 53 na bazie pory dnia
4 stycznia 2025 6 min 71

Automatyczny motyw Bootstrap 5.3 na bazie pory dnia

php
Czytaj więcej
Wizualizacja tematu Long Polling vs Short Polling Porwnanie
21 stycznia 2025 5 min 26

Long Polling vs. Short Polling: Porównanie

php
Czytaj więcej
Wizualizacja tematu Wyraenia regularne i ich obsuga w PHP oraz JavaScript
1 lutego 2025 5 min 19

Wyrażenia regularne i ich obsługa w PHP oraz JavaScript

php
Czytaj więcej
Wymiana doświadczeń

Masz podobne doświadczenia?

Chętnie poznam Twoją perspektywę i porozmawiam o tym temacie szerzej.

Napisz do mnie

Każda perspektywa może wnieść coś wartościowego do dyskusji.

Twoja prywatność i pliki cookies

  1. Ta strona internetowa wykorzystuje wyłącznie niezbędne pliki cookies, które są wymagane do jej prawidłowego działania – m.in. do poprawnego wyświetlania treści, zapamiętania podstawowych ustawień przeglądarki oraz zapewnienia stabilności serwisu.
  2. Nie stosuję plików cookies w celach marketingowych, reklamowych ani analitycznych.
  3. Strona ma charakter wyłącznie informacyjny i nie zawiera formularzy kontaktowych, rejestracyjnych ani zakupowych, przez które dane mogłyby być przesyłane na serwer.
  4. Nie zbieram danych osobowych podczas zwykłego korzystania z witryny.
  5. Serwis nie korzysta z certyfikatu SSL, jednak ze względu na informacyjny charakter strony nie jest wymagane przesyłanie poufnych danych. Zalecam jednak, aby nigdy nie wpisywać haseł ani danych osobowych na stronach bez szyfrowanego połączenia.
  6. Korzystając z tej strony, wyrażasz zgodę na używanie wyłącznie niezbędnych plików cookies.

Więcej informacji znajdziesz w mojej polityce prywatności.