3

私は最近、SOLID、デメテルの法則、DDD などのオブジェクト指向の原則/実践/パラダイムについてよく考えてきましたが、表面化し続けているテーマは、オブジェクトのカーディナリティを強制することです。

オブジェクトの関連付けカーディナリティは、特定のエンティティを特定の数の他のエンティティ オブジェクトにのみ関連付けることを義務付けるビジネス ルールから派生します。たとえば、倉庫を管理するシステムを設計している場合、ビジネス ルールとして、1 つのアイテムを 1 つの倉庫にのみ保管できるようにすることができます。明らかに、ソフトウェア設計内でこれらのルールを強制することは、実装の問題です。

私が疑問に思っているのは、ビジネス ドメインで厳格なカーディナリティ モデルが必要な場合、それを実施する最善の方法は何でしょうか? オフハンドで考えられるテクニックには、次のようなものがあります。

  • 双方向参照- 関連付けられたオブジェクト間の双方向の関連付け (オブジェクト A はオブジェクト B を参照し、オブジェクト B はオブジェクト A を参照します)

    class Warehouse {
      private List<Item> items;
    
      public void RegisterItem(Item obj) {
        if(obj.Warehouse != null)
          throw new ArgumentException("Can only register un-owned item")
    
        items.Add(obj);
        obj.Warehouse = this;
      }
    }
    
  • 所有エンティティをカプセル化する- 所有者がその作成と削除を制御し、実際のエンティティ実装を抽象化する一連の API を介してアクセスを提供できるようにします (オブジェクト A は渡されたエンティティ B を複製するか、渡されたスキーマに基づいてエンティティ B を作成します)。

    class Warehouse {
      private List<Item> items;
    
      public void RegisterItem(Item obj) {
        items.Add((Item)obj.Clone());
      }
    
      public void RegisterItem(ItemDescriptor item) {
        items.Add(new Item(item));
      }
    }
    
  • サード パーティ モニター- カーディナリティの制約を理解しているサード パーティに、オブジェクトの関連付けを適切に作成および接続してもらいます (オブジェクト C は A と B の関係を認識しており、その作成と維持を担当します。このメソッドは C のみが使用でき、クライアントは使用できません。 )

    class Warehouse {
      private List<Item> items;
    
      internal void RegisterItem(Item obj) {
        items.Add(obj);
      }          
    }
    
    class WarehouseItemRegistrationService {
    
      private List<Item> registeredItems;
    
      public void RegisterItem(Warehouse warehouse, Item item) {
        if(registeredItems.Contains(item))
          throw new ArgumentException("Can only register un-owned items");
    
        warehouse.RegisterItem(item);
      }
    }
    

どの技術にも長所と短所があると思います。双方向の関連付けにより、オブジェクト グラフが複雑になり、参照を更新するためのプライベート API が必要になる可能性がありますが、実装は非常に簡単で、ビジネス エンティティ クラスにビジネス制約を埋め込むことができます。所有エンティティをカプセル化すると、エンティティに値ベースの説明を強制することでドメイン モデルが複雑になる可能性がありますが、非常にクリーンです。サード パーティの監視手法は、明示的なカーディナリティの適用を別のクラスに分離しますが、ドメイン モデルも複雑にします。

誰か他の考え、アイデア、またはより良いアプローチがありますか?

4

1 に答える 1

0

アソシエーションを確立することは、どちらのクラスの責任でもありません。リンク作成は仲介業者にお任せください。

WarehouseItemのインスタンスを作成して、関連付けを表す関連付けクラスと、関連付けWarehouseItemFactoryを確立するクラスを作成しますWarehouseItemWarehouseItemFactoryカーディナリティ ルールを適用する責任があります。

于 2012-04-18T23:03:00.610 に答える