2

私の PHP MVC アプリケーションには、Organisations、Employees、および Roles という 3 つの主要なエンティティがあります。各組織には多くの従業員がおり、各従業員には役割があります。

特定の組織について、従業員のリストを表示したいと考えています。各従業員について、名前、住所の詳細、役割名を表示します。

現在、私が見る限り、これを行う最も効率的な方法は、サービス層が従業員のリストを配列として返すことです。ここで、各要素はデータ フィールドの配列 (オブジェクトではありません) です。マッパーでロール テーブルを従業員テーブルに結合すると、正しいロール名が最初の結果セットに含まれ、データベースに再度クエリを実行する必要がなくなります。

別のアプローチは、私のサービス層が Employee オブジェクトのコレクションを返すことです。ただし、この場合、各 Employee オブジェクトはデータベースにクエリを実行して、そのロールの正しい名前を見つける必要があります (ロールが遅延ロードされると仮定します)。これは非常に非効率的ですが、どういうわけかより「オブジェクト指向」に見えます。

Employee がインスタンス化されるたびにロール名を Employee のプロパティとしてロードすることを検討できますが、それでも一意のロール ID への参照を保持する必要があるため、すぐに同期に関する考慮事項があります。

この問題を解決する典型的な方法は何でしょうか??? 私はそれが何百万回も解決されたと確信しています!

ありがとう!

4

1 に答える 1

1

確かに、これは非常に標準的なものです。しかし、私はまだそれに苦労しています。

私の最初の考えは、次のようなものを設定することです:

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 がすべてを理解し、上記の機能 (プロキシ、カスタム リポジトリなど) を提供してくれることがわかりました。

于 2013-02-25T02:47:12.310 に答える