little-hands/ddd-q-and-a

質問が3点あります。長くなってすみません。1つ目は、自己カプセル化についてです「実践ドメイン駆動設計」を読んでいます。「実践ドメイン駆動設計」では自己カプセル化を使用するため、アクセス修飾子がprotected なセッター(Java)を使い...

Opened this issue · 0 comments

Question

質問が3点あります。長くなってすみません。
1つ目は、自己カプセル化についてです
「実践ドメイン駆動設計」を読んでいます。
「実践ドメイン駆動設計」では自己カプセル化を使用するため、アクセス修飾子がprotected なセッター(Java)を使います。
コンストラクタで メンバ変数 name を初期化する際に、this.name = this.setName(aName); にしています。
そのため、同じパッケージ内ならsetNameによって、更新できてしまう状況になっています。
「ドメイン駆動設計 モデリング/実装ガイド」で、松岡さんは、生成条件の強制、ミューテーション条件の強制を提唱し、セッターを削除していました。
「実践ドメイン駆動設計」のやり方についてどう思われますでしょうか?
2つ目は、自己カプセル化のアクセス修飾子についてです。
セッターを完全に使わないと、コンストラクタが肥大化し、privateな セッターを使わないと可読性が落ちることは納得できるのですが、「実践ドメイン駆動設計」ではprotectedにしていた理由について、どう推測できるでしょうか?
3つ目は、Goの自己カプセル化についてです。
また、Go 言語でもオブジェクト(構造体)を public にして、オブジェクトのメソッド(セッター)をprivateにしても、同じ package 内ならセッターで更新できてしまいます。こちらについても、意見や良い方法をご存知でしたらお伺いしたいです。

Answer

①パッケージ内からアクセスさせる理由がなければ、privateにするのが良いと思います。
さらにprivateにするのであればsetter経由ではなく属性を直接変えてもいいので、そこは選択肢に入れてみてください。
②ちょっとprotectedにしている意図はわからないですね。。継承から使われることを想定しているとかでしょうか?
本文に説明がなければ、そこまで深く考えすぎないでもいいかもしれません。
③GOは実務経験なく、GOのプラクティスを存じないので変なことを言ってしまうかもしれませんが、その条件だけであれば同じパッケージに他のオブジェクトを配置しない形ではどうでしょう?
そのエンティティだけパッケージを1段階深くする、など。。