2016-03-19 12 views
0

最初に、私がから来ている場所を理解するのを助けるための小さな紹介:私はこの質問にどのようにタイトルを付けるかわからなかったか、リポジトリトラッキング作業単位の変更。 (私はいくつかの部分を残しておきますWIP)インターフェイスとオブザーバーパターンへのプログラム

interface ChangeListener 
{ 
    public function onSubjectChanged(ChangeSubject $subject, array $data); 
} 
interface ChangeSubject 
{ 
    public function addChangeListener(ChangeListener $listener); 
} 

と私はまた、リポジトリと作業単位を有する:

Iは、結合された2つのインターフェース、ChangeListenerChangeSubjectを有する

interface UnitOfWork extends ChangeSubject 
{ 
    public function commit(); 
    public function hydrateChange(array $data, ArrayService $arrayService); 
} 

interface Repository extends ChangeListener 
{ 
    public function commit() : \bool; 
    public function commitCount() : \int; 
} 

さて、UnitOfWorkの私の実装では、のは、メソッドhydrateChangeで、より正確に、Bookそれを呼ぶことにしましょう、私は簡単に変更、のリポジトリに通知:

$repository->onSubjectChanged($this, $newHydration); 

問題は、リポジトリ内で本のIDを知る必要があることです。しかし、リポジトリの処理方法には、Bookが持つIDを持たないChangeSubjectを受け取ります。

このようなシステムを正しく設計するにはどうすればよいですか?

PHPにジェネリックがあったとしたら、これは可能でしょう。私が好きではないハックな解決策は、instanceofを使用しています。

enter image description here

+0

このシナリオでは、どこかで 'instanceof'を使用することになります。 UnitOfWorkとビジネスオブジェクトを結合したのはなぜですか?ビジネスオブジェクトは、永続性に関連する問題を認識すべきではありません。 –

+0

@SebastianKeßlerBusiness Objectsと永続性の間の依存関係はどこにありますか?それは依存性の逆転であり、永続性は外部からChangeListenerとして注入されますが、誰が何をしたかを追跡するセキュリティサービスのように(セキュリティ用語ではアカウンティング)、他のものも存在する可能性があります。 PHPがジェネリックをサポートする場合、 'instanceof'は必要ありません。 – Flavius

+0

これはDDDと何が関係しているのか分かりません... –

答えて

2

あなたは概念のいくつかを誤解。あなたは以下の権利を取得した場合は、トラックに戻って取得する必要があります

  • は、あなたのドメインオブジェクトでの作業の単位を実装しないでください。作業単位は、変更を追跡する技術的なヘルパーに過ぎません。したがって、作業単位はビジネスオブジェクトを参照します。 「ID32の本は変更されました」と書かれていますが、ビジネスオブジェクトと同じではありません。

  • 集約タイプの具体的なレポジトリを作成します。BookRepositoryは、GetById(BookId),GetByAuthor(Author)などのメソッドを含む必要があります。注:ジェネリックの言語では汎用部品を抽出する機会があるかもしれませんが、PHPではBookのような具体的な集約タイプを扱うのが最善です。

作業単位とリポジトリパターンについて詳しく知ることをお勧めします。あなたがそれらを使用しようとする前にそれらを完全に理解することを確認してください。また、さまざまなリポジトリのバリエーション(コマンドスタイルリポジトリとコレクションスタイルリポジトリなど)を理解して、プロジェクトに合った情報を得てください。

+0

ええ、あなたの最初の箇条書き点について:確かに私はそれらを混在させました。 2番目のものについて:はい、私は本のリポジトリにそれらのメソッドを持っています。 私にとって、どの書籍のどのフィールドが変更されたのかを正確に追跡することは非常に重要です。そのため、操作変換のリストを 'hydrateChange'メソッドで渡すのはそのためです。 私はビジネスロジックとUoWを分割しますが、それぞれの変更を何とか追跡する必要があります。 あなたはこれをどうやって行いますか?idで "汚い"と書いているだけでは、何が変わったのか正確に知る必要があります。 変更を遡及的に計算することはできましたが、それは最適ではありません。 – Flavius

+0

Bookが保存のためにリポジトリに戻されたときの変更の計算(スナップショット比較と呼ばれることが多い)は、それほど悪いことではありません。これは、ほとんどのORMがすぐにサポートするもので、ほとんどのプロジェクトで使用されています。変更が実際に発生したときに知りたいのであれば、集計には*プロキシベースの変更追跡*が必要です。これは自明ではないかもしれないので、それをそのままの形でサポートするORMを探したいかもしれません。 – theDmi

関連する問題