"Fat" Objects or "Slim" Objects ?

"Fat" Objects or "Slim" Objects ?

Old forum URL: forums.lhotka.net/forums/t/7172.aspx


xxxJasonxxx posted on Thursday, June 25, 2009

Is it better to write "fat" objects or "thin" objects?

Let me explain...

Say I need some code to work with data for a Purchase Order, and its related Customer and Vendor. So I write a "PurchaseOrder" object, a "Customer" object, and a "Vendor" object.

Is it better to write a "fat" PurchaseOrder object that contains a Customer child object and a Vendor child object.

Or is it better to write a "slim" PurchaseOrder object that contains a CustomerId and a VendorId ("Id" meaning unique identifier or primary key). And then let the UI developer use two Ids to instantiate the Customer and Vendor objects separately when they're actually needed.

I see some advantage to "fat" approach - you make one call to one factory method and you get everything you might need; maybe this makes life easier on the UI developer.

I see some advantage to "thin" approach - more loosely coupled; less dependency/reference issues if multiple assemblies; possible performance gain if child objects not always needed.

I'm looking at a project I started a long time ago where I took the "fat" approach. And today I'm thinking that maybe I should have done "thin" instead. I'm debating whether to convert it.

Which approach do you think is better and why?

RockfordLhotka replied on Thursday, June 25, 2009

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.

dg78 replied on Friday, June 26, 2009

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.

xxxJasonxxx replied on Friday, June 26, 2009

Sorry, I should have stated this more clearly...

PurchaseOrder:
- Editable object.
- On the UI, this data is always displayed and can be changed.

Customer:
- Read only object.
- On the UI, this data is sometimes displayed and cannot be changed.

Vendor:
- Read only object.
- On the UI, this data is sometimes displayed and cannot be changed.

xxxJasonxxx replied on Monday, June 29, 2009

.

RockfordLhotka replied on Monday, June 29, 2009

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