相性が悪くて不向きなのでは」という考えが生まれたので、理由を記述していきます。導入した経験もないので、考察の浅い意見が含まれている可能性があります。コメントにてご指摘のほどお願いします。使用して作成することで不変にする方法を提案していただきました。実装しようとすると相性が悪いという内容の記事になります。尽きると考えています。具体的な理由を記述します。値オブジェクトやエンティティを生成する際に、コンストラクタでプロパティのバリデーション(いわゆる完全コンストラクタ)を記述します。生成した時点でオブジェクトがドメインルールを守ったオブジェクトであることが保証され、凝集度が高いコードになります。同様のことを実装すると、コンストラクタを実装する必要があり、一般的には以下のような書き方になります。コンストラクタを使えば、ドメインルールを守ったドメインオブジェクトを生成できます。ドメインルールを守っていないと、エラーハンドリング}しかし、コンストラクタの実装自体は言語で強制されているわけではなく、あくまで開発者が一般的に実装しがちなコンストラクタです。そのため、以下みたいに直接構造体を生成したり、ほかのコンストラクタを定義することで、ドメインルールが破綻したドメインオブジェクトを生成できてしまいます。特有の問題ではありませんが、言語が用意しているコンストラクタが存在しないことから指摘しています。自分も、リポジトリからドメインオブジェクト生成用のコンストラクタはバリデーションがないことは割と普通だと考えています。同様のことができるか確認できていないです(これは自身の調査不足です)。原則に沿わなくなってしまいます。結局、人の目で確認して「コンストラクタを使っていない」と指摘するしかありません。関連しますが、コンストラクタのプロパティはほとんどの場合finalで値を固定にするかセッターを実装しません。これは、ドメインオブジェクトのドメインルールを破られる可能性がなくすためのもので、開発者は安心して開発を進められます。finalといった変数を不変にする手段もなければ、メソッドを通さずに直接更新できます。具体的にドメインルールを無視する過程をソースコードで確認します。セッターを実装していない実装です。セッターを実装しなくても。ないので簡単に更新できます。"0123456789"直接変更できるということは、属性を更新するメソッドを作成してバリデーションを強制できない上に、更新のロジックをドメイン外に記述できるため、凝集度が低いコードになります。ため変更の際にはChangeNameメソッドの使用を強制できるため、ドメインルールが守られます。似たような実装が可能です。変更用のメソッドにバリデーションを持たせても。nil}しかし、先述の通り直接代入してもエラーが発生しないため、ドメインルールが破られます。更新できるため(後述)いったん無視します。代入前に引数のバリデーションをその都度実施すればドメインルールを守れますが、凝集度が下がりドメイン知識の漏洩するためドメインモデル貧血症なソースコードができあがります。newName一連の具体例は、さまざまな問題を引き起こします。すべての属性が不変であるはずの値オブジェクトは不変でなくなること、エンティティに必要な一意な識別子も可変なので同一性を用いた比較ができなくなることなどです。目指す高凝集疎結合なソースコードではなくなります。対策は開発者全員に「このドメインオブジェクトの属性に値を代入してはならない、このドメインオブジェクトの属性は代入しても良い」というドメインモデルの周知と教育の徹底になります。実践するために必要ですが、教える側と教わる側の両者にずっと同じ人がいれるわけではありません。そのような場合に、ソースコードで表現できないことやコンパイル時に問題を指摘されないと、人間の保守では限界があります。公開かそうじゃないか(この記事では「非公開」と呼びます)で、スコープを定義します。詳細は以下の記事にまとめました。https://zenn.dev/msksgm/articles/20220527-go-package-scope一見、可変な値(構造体、フィールド)は公開して、不変にしたい値は非公開にすればうまくいきそうですが、そうなりません。存在するメソッドは呼び出し放題ですし、プロパティも更新をやめることができません。