web-dev-qa-db-ja.com

リポジトリを別のリポジトリに依存させる

私は最近、SOLIDの原則を読み進めるために時間を費やしており、コードベースがどのように機能するかを比較することを確認することにしました。

私たちのコードの一部にはリポジトリがあります(リポジトリA)。レコードをリポジトリAから削除する場合は、関連するレコードもリポジトリBから削除する必要があります。したがって、元のコーダーはリポジトリBの具象実装への依存関係を作成しています。リポジトリAのメソッドはトランザクション内にあり、リポジトリAからレコードを削除してから、リポジトリBのメソッドを呼び出して、関連するデータを削除します。

Sの原則についての私の理解は、各オブジェクトには変更する理由が1つだけあるはずですが、私のリポジトリAには変更する理由が2つあるということですか?または私はマークから外れていますか?

29
MrGrumpy

リポジトリは単一の責任を持つ必要があります-1つの種類のエンティティを永続化します。例えば。従業員。他のリポジトリから関連するレコードを削除する必要がある場合、それはビジネスロジックのように見えます。例えば。

従業員が解雇されたら、彼の作業ログを削除する必要があります

そして、ビジネスロジックの通常の場所はドメインサービスです。このサービスには両方のリポジトリがあり、すべての作業を行います。

staffService.Fire(employee)

実装は次のようになります

public class StaffService
{
    private IEmployeeRepository employeeRepository;
    private IWorkLogRepository workLogRepository;
    private IUnitOfWorkFactory uowFactory;

    // inject dependencies

    public void Fire(Employee employee)
    {
        using(var uow = uowFactory.SartNew())
        {
            workLogRepository.DeleteByEmployee(employee.Id);
            employeeRepository.Delete(employee.Id);
            uow.Commit();
        }
    }
}

だから、基本的なアドバイス

  • ビジネスロジックを1か所に維持し、その一部をUIに、一部をリポジトリに、一部をデータベースに広げないでください(場合によっては、パフォーマンスの問題により、データベース側でロジックを実行する必要がありますが、それは例外です)。
  • リポジトリに他のリポジトリを参照させないでください。リポジトリは、非常に単純な責任を持つアプリケーションの非常に低レベルのコンポーネントです

従業員がいて、別のデータベーステーブルに格納されているネストされたオブジェクトがある場合はどうすればよいでしょうか。そのオブジェクトを従業員とは別に使用する場合、すべては上記のとおりです-別のリポジトリと、両方のリポジトリを操作する他のオブジェクト(サービス)が必要です。しかし、ネストされたオブジェクトを従業員とは別に使用しない場合、従業員は集約ルートであり、内部の両方のテーブルをクエリする従業員リポジトリのみが必要です。

51