从域模型检索集合中的项目的最佳实践是什么?

发布于 2024-08-03 08:58:58 字数 1422 浏览 2 评论 0原文

从具有指定属性的域对象内的集合中检索对象的最佳实践是什么?

例如,我们有一个汽车保险应用程序,它有两个类:一个包含汽车列表的人。如果我总是需要从具有指定 VIN 的人那里检索汽车,那么实现该方法的最佳方法是什么?我在下面提供了一些示例 - 欢迎其他人

示例 1
在 Person 实体中添加一个新方法来检索 VIN


    public class Person
    {
         private HashSet<Car> cars = new HashSet<Car>();

         public Set<Car> getCars()
         {
              return this.cars;
         }

         public Car getCarByVin(VIN vin)
         {
              //loop over cars and retrieve the car with the VIN
         }
    }

因此,从应用程序中该过程将是...


    VIN vin = new VIN(...);
    Person person = personDao.getPerson();
    Car personCar = person.getCarByVin(vin); 

示例 2
在 Person 实体中创建一个新的列表集合,并将通过 VIN 方法检索添加到集合中,


    public class Person
    {
         private CarSet cars = new CarSet();

         public CarSet getCars()
         {
              return this.cars;
         }
    }

    public class CarSet
         implements Set<Car>
    {
         //implement required methods for Set

         public Car byVin(VIN vin)
         {
              //loop over set and retrieve the car with the VIN
         }
    }

因此从应用程序中,该过程将是...


    VIN vin = new VIN(...);
    Person person = personDao.getPerson();
    Car personCar = person.getCars().byVin(vin); 

What is the best practice for retrieving an object from a collection within a domain object with a specified property?

For example, we have a car insurance application which has two classes: a Person with a list of Cars. If I always needed to retrieve a Car from a Person with the specified VIN, what is the best way to implement the method? I've provided a few examples below - others are welcome

Example 1
Add a new method within the Person entity to retrieve the VIN


    public class Person
    {
         private HashSet<Car> cars = new HashSet<Car>();

         public Set<Car> getCars()
         {
              return this.cars;
         }

         public Car getCarByVin(VIN vin)
         {
              //loop over cars and retrieve the car with the VIN
         }
    }

So from an application the process would be...


    VIN vin = new VIN(...);
    Person person = personDao.getPerson();
    Car personCar = person.getCarByVin(vin); 

Example 2
Create a new list collection within the Person entity and add the retrieve by VIN method to the collection


    public class Person
    {
         private CarSet cars = new CarSet();

         public CarSet getCars()
         {
              return this.cars;
         }
    }

    public class CarSet
         implements Set<Car>
    {
         //implement required methods for Set

         public Car byVin(VIN vin)
         {
              //loop over set and retrieve the car with the VIN
         }
    }

So from an application the process would be...


    VIN vin = new VIN(...);
    Person person = personDao.getPerson();
    Car personCar = person.getCars().byVin(vin); 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

仅此而已 2024-08-10 08:58:58

我认为德米特法则在这里适用,这有利于第一个例子。任何时候你进行链接,例如 foo.getBar().doBlah(),都会违反德米特定律。这显然不是一条法律,但当一个类必须了解另一个类中的位的太多细节时,它是一个很好的指导方针。

I think the Law of Demeter applies here, which favors the first example. Any time you're chaining, such as foo.getBar().doBlah(), that's breaking the Law of Demeter. It's obviously not a law, but it's a good guideline for when a class has to know too many details about the bits within another class.

萌无敌 2024-08-10 08:58:58

一旦你说具有指定 VIN 的汽车,你就会让我认为这是实体,而不是值对象...另外,如果你需要“检索”它,则意味着它是实体,而不是值。值对象通常不需要被检索,如果需要,您可以即时创建一个...您确定清楚 DDD 中实体和值元素之间的区别吗?

添加:那么如果 Car 是一个实体,从您所说的来看,它似乎应该是一个以 Person 作为聚合根的聚合中的成员实体。 (尽管它可能是它自己的聚合的根)在任何情况下,都应该构建 Person 存储库,以便当您获取聚合时,它也会获取该人的汽车。 Person 类应该具有 Cars 类型或 CarCollection 属性,其名称为 Cars 或 OwnedCars 或其他名称,并且 Type(Cars 或 CarCollection)应该具有一个索引器,用于根据 VIN 检索特定汽车。

public class Person    
{
   private int persId;
   // other fields
   private Cars cars;

   public Cars Cars { get; set; }
   // all other stuff
}

public class Cars: Collection<Car> // or 'public class Cars: List<Car>' or ...
{
    public bool Contains(string VinNumber]
    {
        foreach (Car c in this)
           if (c.VinNumber = VinNumber) return true;
        return false;
    }
    public Car this[string VinNumber]
    {
        get 
        {
            foreach (Car c in this)
                if (c.VinNumber = VinNumber) return c;
            return null;
        }
    }
}

As soon as you say Car with specified VIN, you make me think this is Entity, not value object... Also, if you need to "retrieve" it that implies that it is Entity, not value. Value objects don't generally need to be retrieved, you can just create one on the fly if you need one... Are you sure you are clear on distinction between entity and value elements in DDD?

ADDED: Then if Car IS an entity, from what you've said, it appears that it should be a member entity in an aggregate with Person as the aggregate root. (Although it may be the root of it's own aggregate) In any case, the Person repository should be constructed so that when you fetch the aggregate it also gets the Cars for that person. The Person class should have a property of Type Cars, or CarCollection, which is named Cars, or OwnedCars, or whatever, and the Type (Cars or CarCollection) should have an indexer that retrieves a specific Car based on the VIN.

public class Person    
{
   private int persId;
   // other fields
   private Cars cars;

   public Cars Cars { get; set; }
   // all other stuff
}

public class Cars: Collection<Car> // or 'public class Cars: List<Car>' or ...
{
    public bool Contains(string VinNumber]
    {
        foreach (Car c in this)
           if (c.VinNumber = VinNumber) return true;
        return false;
    }
    public Car this[string VinNumber]
    {
        get 
        {
            foreach (Car c in this)
                if (c.VinNumber = VinNumber) return c;
            return null;
        }
    }
}
離人涙 2024-08-10 08:58:58

在这种情况下,我发现将搜索方法放在对象本身上更容易,而不是尝试对集合类进行子类化(并带来看似简单的决策可能导致的所有设计决策更改)。

以上所有内容都假设基本设计确实是您想要的。不过,我通常更喜欢某种允许我按人和 vin 搜索车辆的外观,而不是搜索人对象本身。

In cases like this, I find it easier to put the search method on the object itself, rather than trying to subclass a collection class (and bringing along all of the design decision changes that can result from that seemingly simple decision).

All of the above assumes that the basic design is really what you want. I'd generally prefer some sort of facade that allows me to search for vehicle by person and vin, rather than searching the person object itself, though.

随遇而安 2024-08-10 08:58:58

我真的不喜欢你的 CarSet 设计。我不希望看到一个专门为此目的而没有专门行为的班级;诚然,这是一个证明观点的简单例子。

但我也反对你的 Person 例子。您有一个对 HashSet 的私有引用,该 HashSet 应该具有静态类型的 Set。然后你有一个 getter 返回对该私有数据成员的引用。您应该意识到这是一个任何人都可以操作的可变引用。你的私有修饰符毫无意义。

在这种情况下,正确的做法是使用 java.util.Collections 类返回对不可变 Set 的引用,以防止客户端修改私有状态。

I really dislike your design with CarSet. I wouldn't like seeing a specialized class for that purpose without specialized behavior; admittedly it's a simple example to demonstrate a point.

But I also object to your Person example. You have a private reference to a HashSet that should have static type of Set. Then you have a getter that returns a reference to that private data member. You should realize that this is a mutable reference that anyone can manipulate. Your private modifier is meaningless.

The right thing to do in that case is to return a reference to an immutable Set, using the java.util.Collections class, to prevent clients from modifying private state.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文