2

プロパティとメソッドが定義された顧客クラスがあります。現在、顧客に関連するあらゆるタイプのタスクのメソッドが含まれています。たとえば、メソッド「InsertOrUpdateCustomer」が含まれています。このメソッドは、新しい顧客レコードをデータベースに挿入するか、既存の顧客レコードの編集を容易にします。

このクラスには、顧客フィールドのいくつかの検証メソッドも含まれています。

それは良い方法ではないと思います。私はこのようにそれをいくらか壊したい:

interface ICustomer
{
    string CustomerName;
    date FinancialYearStartDate;
    date FinancialYearEndDate;
    string TaxNo;
    string Address;
}

このインターフェイスを別のクラスに実装したい、たとえば顧客:

class Customers: ICustomer
{
    // Properties
    CustomerName { get; set; }
    FinancialYearStartDate { get; set; }
    FinancialYearEndDate  { get; set; }
    TaxNo { get; set; }
    Address { get; set; }

    // Constructor
}

私は知りたいです:

  1. 新しい顧客を挿入または更新するためのメソッドをどこに追加しますか? 別のクラスを作成するか、上記のクラスにメソッドを追加する必要がありますか?

  2. 上記の方法で古い単一クラスを壊すことは有益ですか? 上記のコードでインターフェイスにはどのような利点がありますか?

  3. 検証メソッドを削除し、代わりに検証フレームワークを使用したいと考えています。検証を行う別のクラス「CustomerValidations」を作成する必要がありますか、それとも上記のクラス自体を使用する必要がありますか?

4

4 に答える 4

4
  1. 挿入および更新メソッドの場合、CRUD メソッドを使用してリポジトリICustomerRepositoryを作成します (例: )
  2. ICustomer インターフェースの直接的なメリットがわかりません
  3. 検証が事業体の外にあるアプローチを使用します。たとえば、専用の検証クラス、またはspring.net validationのような構成ファイルで。

全体として、ビジネス状態、永続ストレージ、検証など、クラスごとに 1つの責任を持つことは良い考えだと思います。CustomerNHibernateCustomerRepository : ICustomerRepositoryCustomerValidator

リポジトリの例:

interface ICustomerRepository
{
  // Get by id
  Customer Get(int id);
  void Delete(Customer customer);
  IList<Customer> GetAll();
  // creates a new instance in datastore
  // returns the persistent identifier
  int Save(Customer customer);
  // updates if customer exists,
  // creates if not
  // returns persistent identifier
  int SaveOrUpdate(Customer customer);
  // updates customer
  void Update(Customer customer);

  // specific queries
  IList<Customer> GetAllWithinFiscalYear(DateTime year);
  // ...
}

ご覧のとおり、このインターフェイスの最初のメソッドはほとんどのビジネス エンティティで類似しており、次のように抽象化できます。

interface IRepository<TId, TEntity>
{
  // Get by id
  TEntity Get(TId id);
  void Delete(TEntity entity);
  IList<TEntity> GetAll();
  // creates a new instance in datastore
  // returns the persistent identifier
  TId Save(TEntity entity);
  // updates if customer exists,
  // creates if not
  // returns persistent identiefier
  TId SaveOrUpdate(TEntity entity);
  // updates customer
  void Update(TEntity entity);
}

interface ICustomerRepository : IRepository<int, Customer>
{
  // specific queries
  IList<Customer> GetAllWithinFiscalYear(DateTime year);
}
于 2010-11-26T08:39:55.660 に答える
2

私の答え:

  1. ICustomers を含むクラスに Insert メソッドを配置します (1 つ以上あると思います)。更新に関しては、このメソッドが何をするかによって異なります。一部の Customer の内部フィールド/プロパティを更新する場合は、ICustomers を使用する必要があります。

  2. 最大の利点の 1 つである IMHO は、簡単にモック/スタブできるため、顧客に依存するコードの単体テストがはるかに簡単になることです。

  3. クラス自体を使用します。

于 2010-11-26T08:35:54.310 に答える
1

' ' などのアクションInsertOrUpdateCustomerは、通常、(アダプター モデルの) 顧客エンティティ サービスの一部です (つまり、別のクラスで、お勧めします)。

それを考える方法は、「顧客を救うのは誰の責任か」です。

ICustomerValidator1 つの可能性は、aを Save メソッドに「注入」することです。

于 2010-11-26T08:35:11.283 に答える
0

基本的にデータ コンテナであるクラスにインターフェイスを導入しても、ほとんどメリットはありません。代わりに、データベース永続性ロールと検証ロールをそれぞれ持つ 2 つのクラスを作成することができます。インターフェースを使用すると、テストまたはさまざまなストレージ/検証戦略のためにクラスを交換可能にする機会が得られる場合があります。

于 2010-11-26T08:38:33.783 に答える