2011-06-29 5 views
9

あなたは、このようなクラス定義することができますActiveRecordの使用:これはいいとシンプルであるがアクティブレコード対リポジトリ - 賛否両論?

class Contact 
{ 
    private String _name; 
    public String Name 
    { 
    get { return _name; } 
    set 
    { 
     if (value == String.IsNullOrWhiteSpace()) 
     throw new ArgumentException(...); 
     else 
     _name = value; 
    } 
    } 

    public Boolean Validate() { ... /* check Name is unique in DB */ } 

    public Boolean Save() { ... } 

    public static List<Contact> Load() { ... } 
} 

を、私は私のクラスが起こっロジックの大ミックスで非常に肥大化になることがわかりました!レイヤード/ドメインのデザインを使用して

次のような同じクラスを定義することができます:それはアクティブレコード=>階層化設計から移行された

class Contact 
{ 
    [Required(AllowEmptyStrings=false)] 
    public String Name { get; set; } 
} 

class ContactService : IService 
{ 
    public List<Contact> LoadContacts() { return (new ContactRepository()).GetAll(); } 
    public Contact LoadContact(int id) { return (new ContactRepository()).GetById(id); } 
    public Boolean SaveContact(Contact contact) 
    { 
     if (new ContactValidator().Validate(contact)) 
      new ContactRepository().Save(contact); 
    } 
} 

class ContactRepository : IRepository 
{ 
    public List<Contact> GetAll() { ... } 
    public Contact GetById(int Id) { ... } 
    public Boolean Save(Contact contact) { ... } 
} 

class ContactValidator : IValidator 
{ 
    public Boolean Validate(Contact contact) { ... /* check Name is unique in DB */ } 
} 

class UnitOfWork : IUnitOfWork 
{ 
    IRepository _contacts = null; 
    public UnitOfWork(IRepository contacts) { _contacts = contacts; } 
    public Commit() { _contacts.Save(); } 
} 

どのように?

    名セッターで
  • エンティティレベルの検証は=>は、新しい別のContactValidator
  • 保存ロジックにエンティティから移動(DataAnnotation経由ableit)
  • ビジネスロジック/ルールの検証(一意の名前)=>のまま = >
  • (またたUnitOfWorkで)別個のリポジトリパターンクラスに移動ロードロジック=>リポジトリと別のリポジトリ
  • 相互作用がContactValidator、ContactRepositoryの使用を強制する新しいContactService(UnitOfWorkを介してであるに移動等 - レットインに反対ContactRepositoryで発信者を逃がす!)。

このレイヤードデザインのピアの承認/提案を探しています - 通常、アクティブレコードタイプの外ではデザインしません。コメントは感謝しています。

NB - この例では、意図的に単純です(UnitOfWorkのは実際には使われていないとリポジトリ/検証のNEWINGは異なる方法で処理されるだろう)。

答えて

2

両方のアプローチには長所と短所があります。

ふりをして、あなたはActive Record-styledオブジェクトをどこか(深い内側のBL)に渡しています。あなたはそれを読むことができます、あなたはそれを変更することができます、あなたはそれを保存することができます。この場合、BLの部分はあなたのエンティティのインタフェースと結合されるだけです。階層化されたアーキテクチャでは、リポジトリをそのコードにどうにかして渡す必要があります。明示的にそれを渡すか、IoCコンテナを使用するかのどちらかです。

もう1つのポイントは、リポジトリの概念があるときは、リポジトリを持っていることがわかっている、またはリポジトリ内のオブジェクトが削除されているという概念を簡単に定義できます。リポジトリは、分散環境で作業する場合、基本的には非常に便利な通知です。

6

本当にドメインロジックの複雑さによって異なります。たとえば、シンプルなブログを書いていたら、アクティブなレコードがうまくいきます。ほとんどの場合、アプリケーションはデータを保存して読み込みます。シンプルで活発なレコードパターンは、仕事に適したツールです。

しかし、多くの複雑なビジネスルールとプロセスがある配送会社のソフトウェアを作成していた場合、他のDomain Driven Designパターンと一緒にリポジトリパターンを使用すると、長期的にはより保守的なコードが提供されます。あなたの検証を達成するためにspecification patternを使用するドメイン駆動設計を使用して

0

この記事では、両方の良いと簡潔な説明のように思える:私は追加したい https://hashnode.com/post/which-design-pattern-do-you-prefer-active-record-or-repository-cilozoaa5016o6t53mhsdu6nu

の一つは、それはあなたの持続性のニーズが単純で、リポジトリが良好な場合、「アクティブなレコードが良いだけではないですあなたの永続性のニーズが複雑なとき "。ここでのパターンの選択は、デメテルの法則についてどのように感じるかともっと関係があります。あなたのアーキテクチャの異なる部分を完全に分離して、誰かが別の部分を理解することなく理解できるようにするには、Demeterの法則が必要です。それは、仕様が変わる可能性があるプロジェクトの早い段階で、特にこのような抽象化についてあまりにも強迫することは非常に危険だと私は思っていました。プロジェクトの将来の保守担当者を推測してはいけません。スマートで一度に複数のことを考えることができます。そうでない場合は、リポジトリパターンを使用して防ぐことができない大きな問題があるかもしれません。

関連する問題