(主にOPのコメントからの回答ですが、回答を詳しく説明する方がよいと思います)
セッターは元気です。問題は、ドメインエンティティの「ユーザー」がこれらのゲッター/セッターを介してアクセスしてはならないことです。アプリケーション ロジックがこれに基づいて構築されるように、ドメイン エンティティにはビジネス上意味のあるインターフェイスが必要です。セッターは、実装オブジェクトを作成するために使用される実装レベルのものである必要があります(リポジトリなど)
例を使って説明する方が良いと思います。
これは、アンチパターンと見なされるセッターの間違った方法です
class OrderApplicationService {
public void cancelOrder(String orderId) {
Order order = orderRepository.getOrder(orderId);
order.setOrderStatus(CANCELLED);
order.setOpenQuantity(0);
orderRepository.update(order);
}
}
ただし、より正しい方法は次のとおりです。
// Interface for Order
interface Order {
void cancel();
// no setters!!!
}
class OrderImpl extends Order {
@Override
void cancel() {
this.status = CANCELLED;
this.openQuantity = 0;
}
void setId(String orderId) { ... }
// some other setters
}
class OrderApplicationService {
public void cancelOrder(String orderId) {
Order order = orderRepository.getOrder(orderId);
order.cancel();
orderRepository.update(order);
}
}
リポジトリは、ゲッター/セッターにアクセスできるように、impl を介して作成およびアクセスしています。ただし、アプリケーションロジックはインターフェイスのみに直面しており、セッター/ゲッターを使用してロジックを実装していません (これはアンチパターンです)。
上記の方法は、インターフェイスの適切な宣言によって強制されます。ただし、自己評価に頼ることができると思われる場合は、インターフェイスを省略して、ビジネス ロジック関連のメソッドと setter/getter の両方を Impl に直接配置することで、話を単純化できます。また、実装中は、ビジネス ロジックの実装中に (ゲッター/セッターではなく) エンティティのビジネス メソッドのみを使用する必要があることを知っておく必要があります。
また、セッターをアンチ DDD と見なすことは、単純な経験則ではありません。たとえば、フリー テキスト コメントをエンティティに格納する場合など、setter を business-logic-method として提供することは、必ずしも間違った決定であるとは限りません。