2016-05-31 15 views
1

Symfony 3では、ドメイン駆動型設計(DDD)に基づいて次の点をどのように区別しますか?symfonyとドメイン駆動型設計

  • サービス(構成サービス・ファイルに定義されている1)
  • 教義リポジトリ(\教義\ ORM \ EntityRepository)
  • エンティティ(エンティティフォルダ内のクラス)

私は」教義がSymfonyから切り離されていることを認識しています(つまり、完全に省略することができます)。しかし、どちらが教義のないSymfonyプロジェクトのリポジトリですか?または、おそらくSymfony(Doctrineなし)は実際にDDDに実際に従っていないのでしょうか?

編集

私は、コントローラは、プロジェクトのために利用可能なすべての管理職に

class ManagementController 
    public function getAvailableManagers(Array $project) 
    { 
     ... 
    } 
}  

利用可能なマネージャを返す機能を持っている

私の質問をより明確にするために、次のシナリオをモックアップしよう彼らの手にプロジェクトがなく、プロジェクトが専門分野(例えば、顧客サービス、ビジネス関係、物流など)にあることを意味する

ただし、デザインが悪いため、特殊ドメインはデータベースに格納されず、代わりにAPI呼び出しを介して別のHRシステムに呼び出される必要があります。後でそれがデータベースに統合されます

現在、2つの異なるソースから情報を取得しているため、マネージャはリポジトリクラスでなければならないと思います。問題は...これにDoctrine Repositoryを使うべきですか?それとも、それは単なる通常のエンティティか、たぶんサービスなのでしょうか?

class ReplacementInstructionRepository extends \Doctrine\ORM\EntityRepository 
{ 
    private $id; 
    private $name; 
    private $speciality; 
    private $projects; 
} 

これを分割する方法についてのガイドが必要です。私はここにあなたがsymfonyにDDDの原則を適用するプロジェクトのいくつかの例を持って、よく質問を理解していませんが、あなたに

乾杯、

+1

DoctrineとSymfonyがDDDに従っていると思いますか? Symfonyのほとんどのアプリは荒々しいアプリです。該当する場合は、Symfonyを使用してDDDの原則のいくつかに従うことができます。書かれたようにあなたの質問は私には意味をなさない。 – Cerad

+0

フィードバックいただきありがとうございます、私はサンプルシナリオで質問を更新しました。うまくいけばそれは混乱をクリアするでしょう:) –

答えて

4

をありがとうございます。あなたの最後の説明の後

https://github.com/PhpFriendsOfDdd/state-of-the-union/blob/master/README.md

EDIT

は私が:-)、より良い答えを与えることができると思います。

私はSpecification Patternがあなたのシナリオに合っていると言います。仕様パターンを使用すると、ドメインルールでビジネスルールを維持できます。この場合、あなたは、重要なビジネスルールに述べた:彼らは彼らの手の上にプロジェクトを持たないと、プロジェクトがその専門的なドメイン内にあることを

利用可能なマネージャは意味を(例えば、顧客サービス、ビジネス関係、物流など)

この場合、対処しなければならない貧弱な設計について言及しました。グリーンフィールドプロジェクトでは、マネージャーの専門領域をマネージャー内に保存するので、すべてが同じAggregate Root、Manager内に存在します。あなたのケースでは

あなたは以下を参照することができますように、私はリポジトリを介して、外部パーティ(HRシステム)を統合します:使用して(それはリポジトリの具体的な実装であるとして、ファーストクラスという

nampespace xxx\infrastructure\persistence 
class ManagersRepository 
{ 
    public function __construct(HrApiClient $apiClient) 
    { 
     $this->apliClient = $apiClient; 
    } 

    public function findWithoutProjects() 
    { 
     $sqlQuery = //find all managers without project 
     $managers = $this->execute($sqlQuery); 
     foreach ($managers as $manager) { 
      $projects = $this->apliClient->findProjectsOfManagerId($manager->id()); 
      $manager->specialisedIn($projects); //This should be done with reflection 
     } 

     return $managers; 
    } 

    public function selectSatisfying(Specification $specification) 
    { 
     return $specification->satisfyingElementsFrom($this); 
    } 
} 

namespace xxx\Domain 
class ManagersAvailableSpecification implements Specification 
{ 
    public function __construct($aNewProject) 
    { 
     $this->aNewProject = $aNewProject; 
    } 

    public function isSatisfiedBy($manager) 
    { 
     // business rules here... 
     if ($manager->isSpecialisedIn($this->aNewProject)) { 
      return true; 
     } 

     return false; 
    } 

    public function satisfyingElementsFrom(ManagersRepository $managersRepository) 
    { 
     $managers = $managersRepository->findWithoutProjects(); 

     return array_filter(
      $managers, 
      function (Manager $manager) { 
       return $this->isSatisfiedBy($manager); 
      } 
     ); 
    } 
} 

お知らせMySql、Postgreなど)はインフラストラクチャ層に存在します。 2つ目は、インターフェイスに依存するため、使用可能なマネージャを定義するビジネスルールとともに、ドメイン内に存在します。また、将来的にあなたがあなた自身のデータベースへの第三者からの特殊なドメインを移行する場合は、あなただけの1クラスが、他には何を変更する必要があること

class FindAvailableManagersService 
{ 
    private $managersRepository; 

    public function __construct(ManagersRepository $managersRepository) 
    { 
     $this->managersRepository = $managersRepository; 
    } 

    public function execute(FindAvailableManagersRequest $request) 
    { 
     $managersAvailable = $this->managersRepository->selectSatisfying(
      new ManagersAvailableSpecification($request->project()) 
     ); 

     return $managersAvailable; 
    } 
} 

お知らせ:

は今、あなたのようなサービスを持つことができます触れられる:-)

+0

リンクのおかげで、私はそれを読んでいる:) –

+0

私は詳細で私の答えを更新しました。あなたはそれが有用であることを願っています。 – mgonzalezbaile

+0

興味深い...あなたのリポジトリがDoctrine Repository( '\ Doctrine \ ORM \ EntityRepository')を使用していないので、リポジトリに通常のクラスを使用しています。それはDoctrine Repositoryが使えなくなり、注射できないからですか?ありがとう –

1

私はこのためにDoctrine Repositoryを使うべきですか?

これはDDDに関連する最も古典的な誤解だと思います。 ORMのリポジトリとエンティティは、DDDのリポジトリとエンティティとはまったく異なります。彼らはちょうど同じ名前を持っていますが、それはすべてです、あなたはそれらを混乱させるべきではありません。

DDDエンティティはドメイン内に存在し、ドメイン外のクラスに依存しません。 DDDリポジトリインターフェイスはドメイン内で定義され、実装はインフラストラクチャ内にあり、インフラストラクチャの他の部分に依存する可能性があります。したがって、DDDリポジトリインタフェースを実装するには、必要に応じてORMリポジトリを使用できますが、noSQLデータベースなどのリレーショナルデータベースとはまったく異なるデータストレージソリューションを使用できます。

関連する問題