2008-10-01

Data Structures vs Encapsulation

Having read Clean Code I really wanted to blog about data structures (DTO) and encapsulated objects. But I have been busy and someone else beat me to the punch. Uncle Bob also has an article where he outlines his view.

Data Structure Objects

In C# a Data Structure is represented by a class or struct, that has has no logic and exposes all its state through properties(public fields or get/set methods). Its primarily used near the system boundaries, like UI, Service end points, and database access. Anyone can use the exposed data and operate on it, so adding new behavior is easy, but adding new or changing existing data is troublesome.

Encapsulated Objects

Are represented by C# classes/interfaces with methods that operate on data. The data is hidden(encapsulated). Internally the object can have Data Structure Objects as state, and operate on that state. Methods define the operation that can either be a command (changes the state, and returns nothing) or a query (does not change state, and returns something). A Validator could have a Validate command method that validates the internal state, and a ValidationNotifications query that returns the result of the last validation.

Changing the state is easy because it is only know internal in the class, but adding new or changing existing behavior is troublesome, because it changes the contract of the class.

Hybrid Objects

Hybrids often appear because of database and UI concerns. A class exposes it state so that the UI can data bind and the DAL can save the entity. But the same class should also be encapsulated so that the logic only lives with in the object.

So now the class has two distinct responsibilities:

  1. Exposing state for the UI and DAL to use.
  2. Exposing logic for validation etc.

And guess what, if it is combined in a Hybrid Class it has the drawbacks of both, and non of the benefits. So Hybrids should really be avoided, and interesting happen when you don't create hybrids.

Should all my classes be Encapsulated Objects?

NO!

Even though all the cool kids show off their OO skilz, many problems are best solved with a simple Data Structure Class. If your application starts out as a 1 to 1 mapping from the UI to the database tables, there is little need for encapsulated objects. However as the application gets more logic, be sure to place this logic in encapsulated objects. Avoiding the Hybrid trap, this should help make the application more maintainable.

My advice

Keep your data(from a database or the user etc.) in Data Structures and your logic(anything like if/for/while etc) in Encapsulated Classes. The encapsulated Objects are free to use Data Structures directly or contain them as state. Just like adding string, int, bool and any other simple type feels natural, adding a custom made Data Structure as state should also be natural.

2 comments:

Anonymous said...

Hi Morten,
I think we are on nearly the same page. However, the problem I have found with starting with structures and then using objects when the logic starts to kick in is 2-fold.
1. Logic should be first. Assuming we are building a business application and not a database babysitting application we should focus on objects with logic that we test. Storing new things or changed things can wait.

2. Although this sounds good in theory I find junior developers, lazy developers, and even myself not putting logic in the right spot. The user interface gets a Person Data Structure (PersonDS) that exposes age as an integer. The UI needs to make sure only people who are allowed can see pictures of some sexy ladies. (Sorry, first example that came to mind.) The UI then asks the PersonDS for that age number and makes sure it is 18 or greater before showing pictures of the sexy ladies. WRONG. This is a business rule. The UI should ask the Person object if it can see sexy ladies without ever having to know what data (Age...at least today) is necessary to figure it out. My point is that starting this way leads to bad design.

bakkegaard said...

When you write DTO, do you mean Data Transfer Object (as in intended to be sent over the wire) or do you mean PresentationModel (as in intended to be bound to controls in the UI)?