封止ロジック(ドメイン駆動型のデザイン、最良の実践)
-
21-08-2019 - |
質問
更新: 09/02/2009-改質問は、より良い事例を追加恵み.
こんにちは,
私は建物のPHPを使ってアプリケーションをデータマッパーパターン間のデータベースの団体(ドメイン。私の質問は
どの封止は、一般的に行す。
例えば、共通の課題で検索一つ以上のサイト団体からのサイトマッパー、その関連(ホームページの事業体からのページmapper.現在は、うるようになります:
$siteMapper = new Site_Mapper();
$site = $siteMapper->findByid(1);
$pageMapper = new Page_Mapper();
$site->addPage($pageMapper->findHome($site->getId()));
今ことになるかな例だが実際には、それぞれのサイトに関連するロケールのページでは、実際には複数の修正が目的のこのタスクをいいだけに関心があることが最後)してご利用いただけます。
今必要なのはこのサイトおよび関連するホームページでは、ロケール等) 複数の内、ビームが、皆さんの思いの場所に閉じこういうのはすべての理想的にはいようにす:
$someObject = new SomeClass();
$site = $someObject->someMethod(1); // or
$sites = $someObject->someOtherMethod();
に伴うサイトに関してそれに関連した主体を作成しをご用意しています。
同じ問題が発生し保存する場合はこれらのオブジェクトです。言いサイエンティティ関連のホームページの事業体持っていた、と彼らは両方が変更されていないようになります:
$siteMapper->save($site);
$pageMapper->save($site->getHomePage());
再度、些細なものの、この例が容易です。重複コードにまだ適用されます。
思うけるように、中央オブジェクトが注意:
- 検索サイト(現場)nessessary関連団体
- 新しいサイトの主体に伴う新たな事業体
- をサイト(現場)に保存するまで、全ての関連する主体(合いの変更)
なので帰りの質問には、どうすればこのオブジェクトです。
- 既存のマッパーオブジェクト?
- 何かに基づくリポジトリのパターン?*
- 何かのユニットのパターン?*
- 何か?
*い 完全に 理解し、いずれの場としてできるのではないでしょうかのようですね。
ある標準的な方法へのアプローチはこの問題は、人をスプレッドシートをどのように思いを実施です。んな誰にでも完全に実装では、理論。
おかげさ
ジャック
解決
リポジトリ/サービスパターンを使用して、あなたのリポジトリのクラスは、サービスクラスがエンティティの依存関係を取り付けるように追加のロジックを実行する追加の層になり、あなたの各エンティティのための単純なCRUDインターフェースを提供することになります。あなたのアプリの残りの部分は、その後にのみサービスを利用しています。あなたの例では、次のようになります。
$site = $siteService->getSiteById(1); // or
$sites = $siteService->getAllSites();
次にSiteServiceクラスの内部で使用すると、このようなものを持つことになります:
function getSiteById($id) {
$site = $siteRepository->getSiteById($id);
foreach ($pageRepository->getPagesBySiteId($site->id) as $page)
{
$site->pages[] = $page;
}
return $site;
}
私は文法的に間違って何かがある場合もそう言い訳してくださいPHPを知らない。
他のヒント
[編集:この入試に住所があるということが多くを書くのカスタムコードを直接の対応状況ようにすることが求められまみに合わせ問題へのパターンです。]
パターンのナチュラルをコンセプトがない"地図".後年の高性能PHP開発については、非常に直接取扱いにつきまして。このことを考え:
ファイル:Site.php
class Site
{
public static function Select($ID)
{
//Ensure current user has access to ID
//Lookup and return data
}
public static function Insert($aData)
{
//Validate $aData
//In the event of errors, raise a ValidationError($ErrorList)
//Do whatever it is you are doing
//Return new ID
}
public static function Update($ID, $aData)
{
//Validate $aData
//In the event of errors, raise a ValidationError($ErrorList)
//Update necessary fields
}
その後、呼び出すためでどこからでも)、走り:
$aData = Site::Select(123);
Site::Update(123, array('FirstName' => 'New First Name'));
$ID = Site::Insert(array(...))
気をつけなければいけないのだ約OOプログラミングやPHP...PHPを守れない"状態"とのご要望にも、オブジェクトインスタンスだけですぐに破壊されないことが多くあると思います
私はおそらくその後、デザインがために呼び出すものを見るのを待って、どこかのヘルパーメソッドに共通のタスクを抽出することから始めたいです。それが言うには時期尚早だように感じるます。
あなたは何をこのメソッドに名前を付けるのでしょうか?名前は、通常の方法が所属どこでヒントます。
class Page {
public $id, $title, $url;
public function __construct($id=false) {
$this->id = $id;
}
public function save() {
// ...
}
}
class Site {
public $id = '';
public $pages = array();
function __construct($id) {
$this->id = $id;
foreach ($this->getPages() as $page_id) {
$this->pages[] = new Page($page_id);
}
}
private function getPages() {
// ...
}
public function addPage($url) {
$page = ($this->pages[] = new Page());
$page->url = $url;
return $page;
}
public function save() {
foreach ($this->pages as $page) {
$page->save();
}
// ..
}
}
$site = new Site($id);
$page = $site->addPage('/');
$page->title = 'Home';
$site->save();
あなたのサイトhref="http://domaindrivendesign.org/discussion/messageboardarchive/Aggregates.html" rel="nofollow noreferrer">集約ルートが複雑な関連をカプセル化し、一貫性を確保するためにを
するとサイトの集合体を取り出し、移入の責任を負っている SiteRepositoryするを作成(すべてのページを含む)、その子供ます。 あなたは別々のPageRepository(あなたがページ別の集計ルートにしないと仮定して)を必要としません、そして、あなたのSiteRepositoryは、(既存のマッパーを使用することによって、あなたのケースで)だけでなくページのオブジェクトを取得する責任を持つべきです。 ですからます: そして 編集:ここでは、短いDDDガイドのお手伝いをするします用語、私は実際に読んでエヴァンスをお勧めしますが、にあなたは全体像をしたい場合。 $siteRepository = new SiteRepository($myDbConfig);
$site = $siteRepository->findById(1); // will have Page children attached
findById
方法はまた、サイトのすべてのページの子供を見つけるための責任を負うことになります。これはCodeMonkey1が与えた答えと同様の構造を持つことになります、しかし、私はあなたが集計してリポジトリのパターンを使用して、というよりも、このタスクのための具体的なサービスを作成することにより、より多くの利益になると信じています。その子オブジェクトのいずれかを含むサイトの集合体の他の検索/照会/更新が、同じSiteRepositoryを介して行われます。