I think you should always design your objects to match the needs of your user scenario/story/use case.
And I think your objects should exist because they have a responsibility, not because they contain data (unless their only responsibility is to contain data - such as a DTO).
If your user scenario actually has the user editing PO, Customer and Vendor data on a single screen, then you probably need PurchaseOrderEdit, CustomerEdit and VendorEdit objects all contained as child objects of a parent PurchaseOrderEntry object.
That seems really unlikely though, because these are typically different use cases. Typically the person entering POs can't arbitarily create/edit customer data, and they often can't even create/edit vendor data. And even if they can edit vendor data, that's usually a different use case - a different scenario.
A few days ago, I was in the same thoughts as Jason.
So I put, with code generation, in my business objects three possibilities and I activate only one for each BO :
- "fat" object :
_MyCustomer = Customer.GetCustomer(Value)
- search in a NameValueList
_CustomerName = NvlCustomer.Value(Value)
- direct access to the database (of course with dataportal)
_CustomerName = ReadName.GetName("customer", Value)
For some objects we need only name and for others we need all data, it depends of the use case.
Why would PurchaseOrderEdit contain CustomerList or VendorList?
PurchaseOrderEdit might use CustomerList to validate its CustomerId property value (in a business rule). Or PurchaseOrderEdit might use a CustomerIdValidator command object to validate its CustomerId proprty value.
Then again, POE might not have a business rule to validate the CustomerId property, because if it is wrong you'll find out when the database throws an exception during the save process (due to referential integrity), in which case POE might not use CustomerList or a CustomerIdValidator.
Copyright (c) Marimer LLC