0

私は、集約ルートからのリポジトリへのアクセスは悪い習慣とみなされていることを読んだ。 それがある場合は、次の例を考えてみより:DDD:悪い習慣と考えられる集約ルートからリポジトリにアクセスしていますか?

class User { 
    private String username; 
    public void changeUsername(String newUsrname) { 
    // How will I persist username to database if I don't have access to repository from aggregate root? 
    ... 
    } 
} 

私は、集約ルートからリポジトリ へのアクセス権を持っていない場合はどのように私は、データベースへのユーザー名を持続しますか?

class User { 
    private String username; 
    private UserRepository userRepository; 
    public User(UserRepository userRepository) { 
     this.userRepository = userRepository; 
    } 

    public void changeUserName(String newUsername) { 
     this.username = newUserName; 
     userRepository.save(this); 
    } 
} 

または私はDDDの概念で何かを見逃している:

は、私はこのようにそれを参照してください?

+0

あなたの例は、ActiveRecordがDDDではないことを示しています。 – dit

+0

@dit、これをDDDの方法でどのように実現しますか? – Teimuraz

+0

このDDDの例を確認してください:https://github.com/citerus/dddsample-core – dit

答えて

6

私は集計ルートからリポジトリにアクセスできない場合、どのようにユーザー名をデータベースに保存しますか?

現在のプラクティスは通常、ドメインモデルではなくアプリケーションコンポーネントでI/Oを処理します。

Application { 
    void when(ChangeUserName command) { 
     User user = this.userRepository.getUserById(command.userId); 
     user.changeName(command.name); 
     this.userRepository.save(user); 
    } 
} 

推奨ドメイン:ドメインモデルの分離についてVladimir Khorikov

0

だけで(完全に右である)@VoiceOfUnreasonによって与えられた答えはここに集約ルーツにコンストラクタを介してリポジトリを注入する理由について簡単に説明が賢明ではありません少し拡張する:

リポジトリはオブジェクトの上に依存すべきを他の方法ではなく、返されます。この理由は、ロードまたは保存せずに(つまり、リポジトリに依存することなく)、あなたの "ドメインオブジェクト"(それ以降は)が存在することができます(また、テスト可能である必要があります)。

基本的には、ユーザがいるためにはインフラストラクチャの詳細であるMySQL/Mongo/XXXインスタンス接続を提供する必要があります。あなたのドメインは、それがどのように永続化されているかについて知るべきではありません。あなたのドメインは、行動、不変条件、ビジネスルールなどを知っています。

これらの概念は、SRP(Single Responsibility Principle)などのベストプラクティスを適用するのに役立ちます。

+0

この場合、ドメイン私はただのリポジトリインタフェースを通過しており、リポジトリインタフェースはドメインの一部であるため、インフラストラクチャについては何もしません。 – Teimuraz

+0

Userクラスの単体テストについて考えてみましょう。ユーザーの名前を変更するには、空であっても一定の長さなどの不変なものがあるとします。不変量を保証するのはユーザARの責任ですが、永続化、フェッチなどの責任も追加すると、ARPクラスとユニットテストのメンテナンスが難しくなります。 – mgonzalezbaile

関連する問題