So, if I am understanding you correctly, you have a one-to-many relationship between a customer and a contact (so that a customer can have many contacts but a contact can only belong to one customer)?
Not sure what you meant by having "to load an editable customer BO and an editable collection with customerContact BO's, event when only a small modification has to be made to a customerContact", but let me describe how I've addressed this. I am interested in other's comments as well as this was an under-explained scenario in the book, IMO.
I would have a Customer object with a read-only child collection, CustomerContactList, containing read-only CustomerContactInfo child objects. In the form used to edit the Customer object, you would display the list of CustomerContactInfo objects in a list or grid view. To edit a contact's information, you would open another form that is bound to the editable root CustomerContact object.
The trick is in how the CustomerContact object is instantiated. If you are editing an existing item, then it is simply a matter of telling the second form the unique identifier for the item to edit - everything else, including the relationship with the Customer is already established. For a new item, you have a few options.
First, expose a CreateContact() method from your Customer class. This will allow you to instantiate the object and pre-set the Customer object as the parent. The new object would then be passed to and bound to the second form.
Another option is to pass the unique identifier of the parent Customer to the second form which then instantiates the new object passing the identifier to the constructor, i.e. Contact newContact = Contact.NewContact(customerID).
A third option, which works when you have many-to-many relationships, is to have a Contact editable root object that can be instantiated and edited on it's own then add the new object to the Customer's ContactList which will establish the relationship. Again, this is more suited for many-to-many scenerios which it doesn't sound like you are doing.
As I said, I am interested in other's feedback on this as well because I certainly don't know that my approach(es) are the only or best options out there.
HTH
Why wouldn't you have read-only CustomerContactList and CustomerContactInfo objects and then have an editable root CustomerContactEdit object? It sounds like that combination would accomplish your goal. The user can see and select from that read-only list, and an edit dialog (or whatever) can pop up to allow the user to edit a specific contact.
The key to success is to design your objects for each use case independantly. You are describing at least three use cases (background-import, user-creates-customer and user-adds-contact), at least as I understand what you are saying.
You should only try to reuse objects across use cases if their responsibilities match exactly - after you've designed them for each use case.
In other words, design your set of objects for background-import. That means defining their responsiblity, listing their behaviors and collaborators. Do the same for user-creates-customer and user-adds-contact - each one as a totally separate set of objects from the others.
Then you can look across all three (or n) use cases to see if you have objects with the same responsiblity/behavior description in different use cases. If so, you can choose to reuse that object. If not, then you can't.
Regardless, you should always look for behaviors that appear in multiple objects, within or across use cases. These duplicate behaviors should be normalized into a centralized class, and the objects where they originally appeared should then collaborate with this new object/class to gain access to those behaviors. This, in my view, is the primary way you get reuse out of OOD. Not at the object level, but at the behavior level.
Copyright (c) Marimer LLC