Java上級

上級 Javaで学ぶドメイン駆動設計|アンチパターン編

導入

ドメイン駆動設計(DDD)は、ソフトウェア開発においてビジネスの複雑さを管理するための強力なアプローチです。しかし、実際のプロジェクトでは、設計や実装における誤りが発生しやすく、これが「アンチパターン」として知られる失敗例を生むことがあります。本稿では、上級者向けに特化し、ドメイン駆動設計の現場で遭遇しやすいアンチパターンを取り上げ、その問題点と改善策を解説します。

教科書レベルの解説(ドメイン駆動設計)

重要な概念の整理

ドメイン駆動設計では、ドメインモデルを中心に据え、ビジネスロジックを明確に表現します。ドメインモデルは、エンティティや値オブジェクト、集約などの要素で構成され、これらを適切に設計することが成功の鍵となります。特に、ビジネスのルールや制約を正確に反映させることが求められます。

コード例(Java)


public class Order {
    private String orderId;
    private List items;
    
    public Order(String orderId) {
        this.orderId = orderId;
        this.items = new ArrayList<>();
    }
    
    public void addItem(Item item) {
        items.add(item);
    }

    public double calculateTotal() {
        return items.stream().mapToDouble(Item::getPrice).sum();
    }
}

コードの行ごとの解説

  1. クラス`Order`は、注文を表すエンティティです。
  2. フィールド`orderId`は、注文の一意の識別子を保持します。
  3. `items`は、注文に含まれる商品をリストで管理します。
  4. コンストラクタで`orderId`を初期化し、`items`を空のリストで初期化します。
  5. `addItem`メソッドで商品を追加する機能を提供します。
  6. `calculateTotal`メソッドでは、全商品の合計金額を計算します。

アンチパターン編

この例では、`Order`クラスにおけるリスト管理の方法が問題になります。具体的には、`addItem`メソッドで直接`items`リストに商品を追加する設計は、外部からの不正な操作を許すリスクがあります。たとえば、外部のクラスが`Order`の内部状態を直接操作し、予期しない状態を引き起こす可能性があります。

改善策としては、`addItem`メソッドにビジネスロジックを組み込むことが考えられます。例えば、同じ商品が既に追加されている場合には追加を拒否する、または在庫が足りない場合には例外をスローするなどの処理を実装します。

まとめ

  • ドメイン駆動設計では、ビジネスロジックをモデルに組み込むことが重要です。
  • アンチパターンを避けるために、クラスの内部状態を適切に管理する設計を心がける必要があります。