Should POCO Domain Classes Contain Collections? – Object-Oriented Concepts

conceptsdomain-modelobject-orientedrelationships

The question title is not good, but I couldn't think of a way to word it better.

I am used to develop using POCO classes in my projects, that is, domain objects contain absolutely no logic, only data.

I am wondering which is the best approach when dealing with class relationships – to put a collection inside the class or to request it later.

For example, consider we have an e-commerce application, that has Orders, and Items inside those Orders. So we could have (pseudo-code)

class Order
{
     int id;
     List<OrderItem> Items;
}

class OrderItem
{
     Product product;
     int quantity;
}

And then use it (1)

var o = LoadOrder(id);
foreach (var i in o.Items) {

…or we could do:

class Order
{
    int id;
}

And use it this way: (2)

var odr = LoadOrder(id);
var itms = LoadItemsOfOrder(odr);
foreach (var i in itms) { 
    .....

The first way is more compact and more "OOP-ish", but the second way gives more control on how and when items are requested, e.g. what if now I need to request only the items that have quantity > 3 ? And what if I don't use the Items collection at all (e.g. to display only a list of orders) – I will be doing unnecessary queries to the database.

In my older, big projects I've gone with a hybrid approach – the domain classes are of the first flavor but there are various "load" methods, like "LoadOrder" and "LoadOrderWithItems" or "FillOrderObject".

Now I am working on a small, toy project, no customers and crazy deadlines and got time to think on these issues.

I tried searching the web but it is very hard to find a POCO answer not related to Entity Framework. (I am not working in .net this time, but would like to apply these concepts.)

Question: is there a method which is clearly better than the other, or both are valid and "it depends" on my project, if I am aiming for performance or for code clarity and maintainability?.

Best Answer

It's never okay to satisfy hypothetical performance goblins at the expense of fewer lines of code or an API that more clearly expresses the relationship between entities.

So, the first example is preferred. Any decent ORM should be able to lazy-load the collection, and some of the more advanced ones will even let define a property on an entity with a custom loading function, also lazy-loaded. That takes care of both of your use cases without breaking encapsulation of the Order class and exposing its inner data structure.

Related Topic