確かに、これは非常に標準的なものです。しかし、私はまだそれに苦労しています。
私の最初の考えは、次のようなものを設定することです:
class Employee
{
protected $name; //etc
/**
* @var Organization
*/
protected $organization;
/**
* @var Role
*/
protected $role;
// And then getters/setters for Role and Organization
}
次に、EmployeeMapper は次のようになります。
class EmployeeMapper
{
/**
* @Var DB
*/
protectd $db;
public function __construct(DB $db)
{
$this->db = $db
}
public function getEmployeesByOrganization($orgId)
{
// query here that joins employees, roles, and organizations
}
}
これはきれいだと思い、あなたが説明する構造を表しています。
しかし、これに関する問題は、EmployeeMapper が Employee オブジェクトを構築する必要がある場合、結合されたクエリ結果の役割フィールドと組織フィールドが役割オブジェクトと組織オブジェクトのフィールドにどのようにマップされるかを知る必要があることです。私にとって、その知識は RoleMapper と OrganizationMapper 内に厳密に存在する必要があります。したがって、これらのマッパーは、このマッピング機能をパブリック メソッドとして利用可能にする必要があり、RoleMapper および OrganizationMapper インスタンスを使用するために EmployeeMapper に挿入する方法が必要です。ZF ベースの例については、Surviving The Deep Endを参照してください。
さらに、あなたが提供した「従業員のリストを表示する」例のように、添付されたロールおよび組織エンティティに関する情報を入手したい場合があるようです。その場合、オブジェクト グラフを結合して構築するオーバーヘッドは正当化されます (役割と組織に対して別々のループ内クエリを実行するよりも確実に優れています)。しかし、名前や電話番号など、1 人の従業員の単純な従業員情報だけが必要な場合もあります。この後者の場合、完全なオブジェクト グラフを結合して構築するというオーバーヘッドが発生するのはなぜでしょうか?
これらの問題にはアーキテクチャ上の解決策があり、通常はプロキシ オブジェクト (Role オブジェクトと Organization オブジェクトの代わりになり、必要に応じてそれらを遅延ロードする) とカスタム リポジトリ オブジェクト (結合を強制する場所) を使用します。
しかし、これらすべてを自分で設計するのは大変だと思います。最終的に、 Doctrineのような ORM がすべてを理解し、上記の機能 (プロキシ、カスタム リポジトリなど) を提供してくれることがわかりました。