+2  A: 

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;
        }
    }
}
Charles Bretana
+1 useful questionning
KLE
I think this would have been better as a comment than as an "answer".
jsight
You're probably right; it would seem that this is an entity object. Thanks Charles.
Jared Pearson
Then see my edited answer...
Charles Bretana
The question said that this was Java code. The code above is C#. :)
jsight
Just as jsight said, C# isn't going help however the concept is like what was given in Example 2. Is that right and if not, how is it different?
Jared Pearson
+1  A: 

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.

jsight
For some of the other applications, there have been a "Service" layer that creates a facade over the data access logic. Is that what you are suggesting?<pre><code>public class CarFinderService { public Car findCar(PersonId personId, VIN vin) { //find the car with the VIN for the person specified } }</code></pre>
Jared Pearson
@Jared - Yes, something along those lines.
jsight
+3  A: 

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.

Chris Kessel
Ah yes, the LoD... you are correct - the first is better than the second because of the hiding of details. Thanks Chris!
Jared Pearson
+1  A: 

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.

duffymo
You are correct, Collections.unmodifiableXXX() methods are our friends. For this example, I want to keep it easy to read and omitted it. Thanks Duffy!
Jared Pearson