Laravel рдореЗрдВ CQRS / ES рдХреЛ рдЬрд▓реНрджреА рд╕реЗ рдХреИрд╕реЗ рдЖрдЬрд╝рдорд╛рдПрдБ рдпрд╛ PHP рдореЗрдВ рдмреИрдВрдХ рд▓рд┐рдЦреЗрдВ


рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдЬрд╕реНрддрд╛ рдЙрддреНрдкрд╛рджрди рдкреЙрдбрдХрд╛рд╕реНрдЯ рдореЗрдВ, рдореЗрд░реЗ рджреЛрд╕реНрддреЛрдВ рдФрд░ рдореИрдВрдиреЗ рдПрд▓рд┐рдХреНрд╕рд┐рд░ рдореЗрдВ рд╕реАрдХреНрдпреВрдЖрд░рдПрд╕ / рдИрдПрд╕ рдкреИрдЯрд░реНрди рдФрд░ рдЗрд╕рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдХреБрдЫ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдкрд░ рдЪрд░реНрдЪрд╛ рдХреАред рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдЕрдкрдиреЗ рдХрд╛рдо рдореЗрдВ рд▓рд╛рд░рд╡реЗрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ, рдпрд╣ рдЗрдВрдЯрд░рдиреЗрдЯ рдореЗрдВ рддрд▓реНрд▓реАрди рдирд╣реАрдВ рдХрд░рдиреЗ рдФрд░ рдЗрд╕ рдврд╛рдВрдЪреЗ рдХреЗ рдкрд╛рд░рд┐рд╕реНрдерд┐рддрд┐рдХ рддрдВрддреНрд░ рдореЗрдВ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рдХреИрд╕реЗ рдбреБрдмреЛрдирд╛ рд╣реИ, рдпрд╣ рдкрд╛рдк рдерд╛ред


рдореИрдВ рдХрдЯ рдХреЗ рддрд╣рдд рд╕рднреА рдХреЛ рдЖрдордВрддреНрд░рд┐рдд рдХрд░рддрд╛ рд╣реВрдВ, рдореИрдВрдиреЗ рдпрдерд╛рд╕рдВрднрд╡ рд╡рд┐рд╖рдп рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреАред


рдХреБрдЫ рдкрд░рд┐рднрд╛рд╖рд╛рдПрдБ


CQRS (рдХрдорд╛рдВрдб рдХреНрд╡реЗрд░реА рд░рд┐рд╕реНрдкреЙрдиреНрд╕рд┐рдмрд┐рд▓рд┐рдЯреА рд╕реЗрдЧреНрд░реАрдЧреЗрд╢рди) - рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕рдВрд╕реНрдерд╛рдУрдВ рдореЗрдВ рдСрдкрд░реЗрд╢рди рдкрдврд╝рдиреЗ рдФрд░ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдЖрд╡рдВрдЯрдиред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдорд╛рд╕реНрдЯрд░ рдХреЛ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдкреНрд░рддрд┐рдХреГрддрд┐ рд╕реЗ рдкрдврд╝рддреЗ рд╣реИрдВред CQRSред рддрдереНрдп рдФрд░ рдЧрд▓рддрдлрд╣рдореА - рдЖрдкрдХреЛ рдЬрд╝реЗрди рд╕реАрдХреНрдпреВрдЖрд░рдПрд╕ рдХреА рдкреВрд░реА рд╕рдордЭ рдкрд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ
ES (рдЗрд╡реЗрдВрдЯ рд╕реЛрд░реНрд╕рд┐рдВрдЧ) - рдПрдХ рдЗрдХрд╛рдИ рдпрд╛ рд╕рдВрд╕реНрдерд╛рдУрдВ рдХреЗ рд╕реЗрдЯ рдХреЗ рд╕рднреА рд░рд╛рдЬреНрдп рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХрд╛ рднрдВрдбрд╛рд░рдгред
CQRS / ES рдПрдХ рд╡рд╛рд╕реНрддреБрд╢рд┐рд▓реНрдк рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдИрд╡реЗрдВрдЯ рдЯреЗрдмрд▓ рдореЗрдВ рдПрдХ рдЗрдХрд╛рдИ рдХреЗ рд░рд╛рдЬреНрдп рдкрд░рд┐рд╡рд░реНрддрди рдХреА рд╕рднреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рд╕рд╣реЗрдЬрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдореЗрдВ рдПрдХ рдПрдЧреНрд░реАрдЧреЗрдЯ рдФрд░ рдПрдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯрд░ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред
рдПрдЧреНрд░реАрдЧреЗрдЯ - рдореЗрдореЛрд░реА рдореЗрдВ рд╕реНрдЯреЛрд░ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╡реНрдпрд╛рдкрд╛рд░ рддрд░реНрдХ рдирд┐рд░реНрдгрдпреЛрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдЧреБрдг рд╣реИрдВ (рд▓реЗрдЦрди рдХреЛ рдЧрддрд┐ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП), рдирд┐рд░реНрдгрдп рд▓реЗрддрд╛ рд╣реИ (рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ) рдФрд░ рдШрдЯрдирд╛рдУрдВ рдХреЛ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред
рдкреНрд░реЛрдЬреЗрдХреНрдЯрд░ - рдШрдЯрдирд╛рдУрдВ рдХреЛ рд╕реБрдирддрд╛ рд╣реИ рдФрд░ рдЕрд▓рдЧ рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдпрд╛ рдбреЗрдЯрд╛рдмреЗрд╕ (рддреЗрдЬреА рд╕реЗ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП) рдХреЛ рд▓рд┐рдЦрддрд╛ рд╣реИред



рд▓рдбрд╝рд╛рдИ рдореЗрдВ


рд▓рд╛рд░рд╡реЗрд▓ рдЗрд╡реЗрдВрдЯ рдкреНрд░реЛрдЬреЗрдХреНрдЯрд░ - рд▓рд╛рд░рд╡реЗрд▓ рдХреЗ рд▓рд┐рдП CQRS / ES рд▓рд╛рдЗрдмреНрд░реЗрд░реА
рд▓рд╛рд░рдмреИрдВрдХ рдПрдХ CQRS / ES рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде рдПрдХ рднрдВрдбрд╛рд░ рд╣реИред рд╣рдо рдЗрд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рд▓реЗ рдЬрд╛рдПрдВрдЧреЗред


рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдЖрдкрдХреЛ рдмрддрд╛рдПрдЧрд╛ рдХрд┐ рдХрд╣рд╛рдВ рджреЗрдЦрдирд╛ рд╣реИ рдФрд░ рдпрд╣ рдмрддрд╛рдирд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреНрдпрд╛ рд╣реИред рд╣рдо рдИрд╡реЗрдВрдЯ-рдкреНрд░реЛрдЬреЗрдХреНрдЯрд░ . php рдлрд╝рд╛рдЗрд▓ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВред рдХрд╛рдо рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ:


  • projectors - рд░рдЬрд┐рд╕реНрдЯрд░ рдкреНрд░реЛрдЬреЗрдХреНрдЯрд░;
  • reactors - рд░рдЬрд┐рд╕реНрдЯрд░ рд░рд┐рдПрдХреНрдЯрд░ред рд░рд┐рдПрдХреНрдЯрд░ - рдЗрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдЗрд╡реЗрдВрдЯ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдореЗрдВ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯреНрд╕ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ, рдпрджрд┐ рдЖрдк рддреАрди рдмрд╛рд░ рдирд┐рдХрд╛рд╕реА рдХреА рд╕реАрдорд╛ рдХреЛ рдкрд╛рд░ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ MoreMoneyNeeded рдИрд╡реЗрдВрдЯ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЙрд╕рдХреА рд╡рд┐рддреНрддреАрдп рдХрдард┐рдирд╛рдЗрдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд╕рдВрджреЗрд╢ рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИ;
  • replay_chunk_size - рд░рд┐рдкреНрд▓реЗ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ред рдИрдПрд╕ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдШрдЯрдирд╛рдУрдВ рд╕реЗ рдЗрддрд┐рд╣рд╛рд╕ рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИред рдЗрд╕ рд╕реЗрдЯрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдСрдкрд░реЗрд╢рди рдХреЗ рджреМрд░рд╛рди рдореЗрдореЛрд░реА рд░рд┐рд╕рд╛рд╡ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд▓рд╛рд░рд╡реЗрд▓ рдЗрд╡реЗрдВрдЯ рдкреНрд░реЛрдЬреЗрдХреНрдЯрд░ред

рдкреНрд░рд╡рд╛рд╕ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВред рдорд╛рдирдХ рд▓рд╛рд░рд╡рд▓ рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣реИ


  • stored_events - рдореЗрдЯрд╛ рдИрд╡реЗрдВрдЯ рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рдЕрд╕рдВрд░рдЪрд┐рдд рдбреЗрдЯрд╛ рдХреЗ рдХрдИ рд╕реНрддрдВрднреЛрдВ рдХреЗ рд╕рд╛рде рдореБрдЦреНрдп ES рддрд╛рд▓рд┐рдХрд╛, рд╣рдо рдИрд╡реЗрдВрдЯ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рд╣реИрдВред рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕реНрддрдВрдн aggregate_uuid - рдЗрд╕рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╕рднреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдореБрдЪреНрдЪрдп рдХреЗ рдпреВрдЖрдИрдбреА рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ;
  • accounts - рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЦрд╛рддреЛрдВ рдХреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯрд░ рдХреА рддрд╛рд▓рд┐рдХрд╛, рд╢реЗрд╖ рд╕реНрдерд┐рддрд┐ рдкрд░ рд╡рд░реНрддрдорд╛рди рдбреЗрдЯрд╛ рдХреА рддреНрд╡рд░рд┐рдд рд╡рд╛рдкрд╕реА рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ;
  • transaction_counts - рдкреВрд░реНрдг рдХрд┐рдП рдЧрдП рд▓реЗрдирджреЗрди рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рддреНрд╡рд░рд┐рдд рд╡рд╛рдкрд╕реА рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд▓реЗрдирджреЗрди рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯрд░ рдХреА рдПрдХ рддрд╛рд▓рд┐рдХрд╛ред

рдФрд░ рдЕрдм рдореИрдВ рдПрдХ рдирдпрд╛ рдЦрд╛рддрд╛ рдмрдирд╛рдиреЗ рдХреЗ рдЕрдиреБрд░реЛрдз рдХреЗ рд╕рд╛рде рд╕рдбрд╝рдХ рдкрд░ рд╣рд┐рдЯ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВред


рдЦрд╛рддрд╛ рдирд┐рд░реНрдорд╛рдг


рдорд╛рдирдХ resource рд░реВрдЯрд┐рдВрдЧ рдПрдХрд╛рдЙрдВрдЯреНрд╕рдХрдВрдЯреНрд░реЛрд▓рд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рд╣рдо store рд╡рд┐рдзрд┐ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ


 public function store(Request $request) { $newUuid = Str::uuid(); //   ,   uuid  //      AccountAggregateRoot::retrieve($newUuid) //           ->createAccount($request->name, auth()->user()->id) //          ->persist(); return back(); } 

AccountAggregateRoot рдХреЛ рд▓рд╛рдЗрдмреНрд░реЗрд░реА AggregateRoot рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реАред рдЖрдЗрдП рдХрдВрдЯреНрд░реЛрд▓рд░ рдирд╛рдордХ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рджреЗрдЦреЗрдВред


 //  uuid      public static function retrieve(string $uuid): AggregateRoot { $aggregateRoot = (new static()); $aggregateRoot->aggregateUuid = $uuid; return $aggregateRoot->reconstituteFromEvents(); } public function createAccount(string $name, string $userId) { //        //  ,   recordThat,  ,    , // ..     ) $this->recordThat(new AccountCreated($name, $userId)); return $this; } 

storeMany рд╡рд┐рдзрд┐ storeMany рдкрджреНрдзрддрд┐ storeMany рдЗрд╡реЗрдВрдЯ-рдкреНрд░реЛрдЬреЗрдХреНрдЯрд░ рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдореЙрдбрд▓ storeMany stored_event_model ред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ stored_event_model рд░реВрдк рдореЗрдВ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ, StoredEvent


 public static function storeMany(array $events, string $uuid = null): void { collect($events) ->map(function (ShouldBeStored $domainEvent) use ($uuid) { $storedEvent = static::createForEvent($domainEvent, $uuid); return [$domainEvent, $storedEvent]; }) ->eachSpread(function (ShouldBeStored $event, StoredEvent $storedEvent) { //   ,     // QueuedProjector* Projectionist::handleWithSyncProjectors($storedEvent); if (method_exists($event, 'tags')) { $tags = $event->tags(); } //         $storedEventJob = call_user_func( [config('event-projector.stored_event_job'), 'createForEvent'], $storedEvent, $tags ?? [] ); dispatch($storedEventJob->onQueue(config('event-projector.queue'))); }); } 

* рдХрддрд╛рд░рдмрджреНрдзрдкреНрд░рдХрд╛рд░рдХ


рдкреНрд░реЛрдЬреЗрдХреНрдЯрд░ рдЕрдХрд╛рдЙрдВрдЯрдкреНрд░реЛрдЬреЗрдХреНрдЯрд░ рдФрд░ рдЯреНрд░рд╛рдВрдЬреИрдХреНрд╢рдирдХрд╛рдЙрдВрдЯрдкреНрд░реЛрдЬреЗрдХреНрдЯрд░ Projector рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ Projector рдЗрд╕рд▓рд┐рдП рд╡реЗ рдЕрдкрдиреА рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдШрдЯрдирд╛рдУрдВ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдВрдЧреЗред


рдареАрдХ рд╣реИ, рдПрдХ рдЦрд╛рддрд╛ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореИрдВ рдпрд╣ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдХреНрд▓рд╛рдЗрдВрдЯ рдЗрд╕реЗ рдХреИрд╕реЗ рдкрдврд╝реЗрдЧрд╛ред


рдЪрд╛рд▓рд╛рди рдкреНрд░рджрд░реНрд╢рди


 //    `accounts`     id public function index() { $accounts = Account::where('user_id', Auth::user()->id)->get(); return view('accounts.index', compact('accounts')); } 

рдпрджрд┐ рдЦрд╛рддреЛрдВ рдХрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯрд░ QueuedProjector рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдХреБрдЫ рднреА рдирд╣реАрдВ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛ рдЬрдм рддрдХ рдХрд┐ рдШрдЯрдирд╛ рдХреЛ рдмрджрд▓реЗ рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


рдЕрдВрдд рдореЗрдВ, рд╣рдо рдпрд╣ рдЕрдзреНрдпрдпрди рдХрд░реЗрдВрдЧреЗ рдХрд┐ рдЦрд╛рддреЗ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдзрди рдХреА рд╡рд╛рдкрд╕реА рдФрд░ рдирд┐рдХрд╛рд╕реА рдХреИрд╕реЗ рд╣реЛрддреА рд╣реИред


рдЯреЙрдк-рдЕрдк рдФрд░ рдирд┐рдХрд╛рд╕реА


рдлрд┐рд░ рд╕реЗ, рдЕрдХрд╛рдЙрдВрдЯрдХрдВрдЯреНрд░реЛрд▓рд░ рдХреЛ рджреЗрдЦреЗрдВ :


 //    uuid  //       //   ,     public function update(Account $account, UpdateAccountRequest $request) { $aggregateRoot = AccountAggregateRoot::retrieve($account->uuid); $request->adding() ? $aggregateRoot->addMoney($request->amount) : $aggregateRoot->subtractMoney($request->amount); $aggregateRoot->persist(); return back(); } 

AccountAggregateRoot рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ


рдЦрд╛рддрд╛ рднрд░рдиреЗ рдХреЗ рдмрд╛рдж:


 public function addMoney(int $amount) { $this->recordThat(new MoneyAdded($amount)); return $this; } //    ""  recordThat // AggregateRoot*? //     apply(ShouldBeStored $event), //       'apply' . EventClassName  // ,     `MoneyAdded` protected function applyMoneyAdded(MoneyAdded $event) { $this->accountLimitHitInARow = 0; $this->balance += $event->amount; } 

* рдПрдЧреНрд░реАрдЧреЗрдЯрдЯреНрд░реВрдЯ


рдзрдирд░рд╛рд╢рд┐ рдирд┐рдХрд╛рд▓рддреЗ рд╕рдордп:


 public function subtractMoney(int $amount) { if (!$this->hasSufficientFundsToSubtractAmount($amount)) { //        $this->recordThat(new AccountLimitHit()); //      ,  //   ,     //     if ($this->needsMoreMoney()) { $this->recordThat(new MoreMoneyNeeded()); } $this->persist(); throw CouldNotSubtractMoney::notEnoughFunds($amount); } $this->recordThat(new MoneySubtracted($amount)); } protected function applyMoneySubtracted(MoneySubtracted $event) { $this->balance -= $event->amount; $this->accountLimitHitInARow = 0; } 


рдирд┐рд╖реНрдХрд░реНрд╖


рдореИрдВрдиреЗ Laravel рдкрд░ CQRS / ES рдореЗрдВ "рдСрдирдмреЛрд░реНрдбрд┐рдВрдЧ" рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рддрд╛рдХрд┐ рдкрд╛рдиреА рд╕реЗ рдореБрдХреНрдд рд╣реЛ рд╕рдХреЗред рдЕрд╡рдзрд╛рд░рдгрд╛ рдмрд╣реБрдд рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рд▓реЗрдХрд┐рди рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рдмрд┐рдирд╛ рдирд╣реАрдВред рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдпрд╛рдж рд░рдЦреЗрдВ:


  • рдЕрдВрддрддрдГ рд╕реНрдерд┐рд░рддрд╛;
  • рдЕрд▓рдЧ-рдЕрд▓рдЧ рдбреЛрдореЗрди рдореЗрдВ DDD рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╡рд╛рдВрдЫрдиреАрдп рд╣реИ, рдЖрдкрдХреЛ рдЗрд╕ рдкреИрдЯрд░реНрди рдкрд░ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдПрдХ рдмрдбрд╝рд╛ рд╕рд┐рд╕реНрдЯрдо рдирд╣реАрдВ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рд┐рдП;
  • рдШрдЯрдирд╛ рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд╕реНрдХреАрдорд╛ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдмрд╣реБрдд рджрд░реНрджрдирд╛рдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ;
  • рдпрд╣ рдШрдЯрдирд╛рдУрдВ рдХреА рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдХреА рдкрд╕рдВрдж рд╕реЗ рд╕рдВрдкрд░реНрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рд░реНрдердХ рд╣реИ, рдЬрд┐рддрдиреА рдЕрдзрд┐рдХ рдареЛрд╕ рдШрдЯрдирд╛рдПрдВ рд╣реИрдВ, рдЙрддрдирд╛ рд╣реА рд╡реЗ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рд╣реЛрдВрдЧреЗ рдФрд░ рдЙрдирдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред

рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдиреЛрдЯрд┐рд╕ рдХрд░рдиреЗ рдореЗрдВ рдореБрдЭреЗ рдЦреБрд╢реА рд╣реЛрдЧреАред

Source: https://habr.com/ru/post/hi448000/


All Articles