2016-11-17 94 views
2

我正在閱讀關於書籍DDD in PHP的預測,我很困惑何時何地從投影儀類中調用註冊方法。PHP中的DDD - >投影機 - >何時何地應該調用投影機的註冊方法?

Flow: CreateNewTaskRequest - > CreateNewTaskService - > Task :: writeFromNew() - > PDOTaskRepository。

在PDOTaskRepository的保存方法結束時,調用投影儀的項目方法,這反過來會調用正在監聽給定域事件的所有已註冊投影的項目方法。

但是何時何地向投影儀注冊投影?

class PDOTaskRepository implements TaskRepository 
{ 
    private $projector; 

    public function __construct(Projector $projector) 
    { 
     $this->projector = $projector; 
    } 

    public function save(Task $task) 
    { 
     // Code to save in DB 


     $this->projector->project($task->recordedEvents()); 
    } 
} 


class Projector 
{ 
    /** 
    * @var Projection[] 
    */ 
    private $projections = []; 


    /** 
    * @param Projection[] $projections 
    */ 
    public function register(array $projections) 
    { 
     foreach ($projections as $projection) { 
      $this->projections[$projection->listensTo()] = $projection; 
     } 
    } 

    public function project(array $events) 
    { 
     foreach ($events as $event) { 
      if (isset($this->projections[get_class($event)])) { 
       $this->projections[get_class($event)]->project($event); 
      } 
     } 
    } 
} 
+0

你正在尋找的東西是pub/sub模式。 – Dariss

+0

這些同步投影是? – plalx

+0

@plalx是的,它是同步的 –

回答

1

有很多方法可以做到這一點。但是,鑑於您的類不是線程安全的,您必須在沒有爭用的地方執行此操作。我會在我的應用程序的Composition Root中直接或通過利用應用程序啓動掛鉤(如果有的話)直接或間接地執行此操作。

此外,爲了最大限度地減少有人濫用Projectorregister函數的風險,我可能會在構造Projector類時通過所有投影。這消除了稍後有人呼叫register可能與正在進行的project操作產生爭用的風險。