Welcome

You have reached the blog of Keith Elder. Thank you for visiting! Feel free to click the twitter icon to the right and follow me on twitter.

How To Not Screw Up Your Application Object Model – Don’t Go All OOP On Me!

Posted by Keith Elder | Posted in .Net, CSLA.Net, Programming | Posted on 02-05-2008

12

I have no idea where this post is going to go but I have several things that have come up in discussion lately with developers that I need to get out.  The conversations I’ve been having are around building applications and using the CSLA.Net business object framework.  This article doesn’t focus on CSLA.Net so even if you aren’t using it, these principals still apply.  This post stems from conversations with developers that are spending a lot of time creating beautiful object models.  I’ve seen developers spend a lot of time on perfecting the object model of an application based on sound OOP practices and techniques.  Once the object model is applied to the application it doesn’t work and the developers are scratching their heads asking themselves why.   I’ll explain a common scenario that I’m running into, how to avoid it, and how I think you should think about your object model for your applications.  Definitely fun bathroom reading, so let’s get going!

Throw Away The Object Model In Your Head

As object oriented programming developers on the .Net and or Java platforms we’ve always been taught and trained to think in object models and object graphs.  For example if I asked experienced object oriented programming developers to create an object model for a Veterinary Clinic they would start immediately thinking in terms of physical objects like, dogs, cats, birds, etc.  The reason is because we have been beat to death with OOP principles.  As an exercise I opened up Visual Studio and threw out the very first object model that came to mind based on a Veterinary Clinic.  Here’s what I came up with thinking about the object model from a pure educational standpoint.  I’d kept going but I wanted it to fit onto one screen.

image

Without knowing anything about the business of a vet clinic and relying only on my experience in owning pets this is the first thing I came up with.  My thought process was vets take care of pets, there are all types of pets, and pets belong to an owner.  Some pets are birds, some are dogs, cats, snakes, lizards, etc.  My college professor would be very proud of my object model I am sure.  He’d feel all warm and fuzzy seeing that I broke down my objects all the way down to dogs then the subclass of spaniels and then cocker spaniels (of which I own three).  On paper this looks great but it is an extremely bad object model.  Don’t do this!  The problem is developers try to apply these perfect object models to their applications.  This is the worst thing a developer can do when building an application.  Well, not the worst, but it sure is a really bad start and a lot of wasted time.

After doing this little exercise I have to admit I felt very dirty.  Seriously.  Why?  Because none of these objects fit into the what the Veterinary Clinic really needs and I honestly just wasted my time proving a point trying to stop you from wasting your time.  Stay with me and I’ll show you. 

A Real Example

I have a friend that is a vet.  After writing this really bad object model down I gave him a call and asked him if he had any software he used to run his clinic.  He said absolutely and he couldn’t run his business without it.  Great, a real world example!

I asked him to tell me about one of the screens they use the most in their application.  He then described what he called the “Account Locator” which after further questioning turned out to be a fancy name for a “Search” screen to lookup clients or accounts in the system.  I took a few mental notes during our conversation and after hanging up made this mock application based on his description. 

image

The scenario is employees running the main desk at the clinic need to get to accounts quickly and this is why this screen  is used so much.  The scenario is if someone calls the clinic to schedule an appointment, the first thing someone has to do is lookup their account.  The grid below displays some useful information to help the employee find the right account.  It also allows the employee to make the client feel like they are well known.  The example my friend gave is once an account is located the employee immediately knows the pet(s) name, the last time they came in and the type of the pet. 

This scenario now brings me back full circle to the object model I initially built.  Here’s the million dollar question: 

What good is a gigantic object model in this scenario?  Answer:  Nothing! 

The elaborate object model I built out based on my first impression of what objects I’d needed to create are basically useless. 

Why?  For starters, look at where the information from the object model (which shouldn’t have been written in the first place) has to come from just to make this screen work. 

image

Data is traveling from all sorts of different objects and I didn’t even account for all of the fields.  Are you starting to see why building elaborate object models for an application first doesn’t work?  If you don’t know how the data is going to be used you can’t build an object model. 

This is the main point.  Focus on the business requirements and don’t get all caught up in OOP principles just because it is fun.  And it is fun to be honest.  I love discussing object models but the point is you should be discussing the business requirements!

Do We Really Need An Object Then?

The question I get after showing someone the above example is, “Do we really need an object then since we are just fetching data?”.  When people ask me this what they mean is if they are just searching data and returning data, why all the emphasis on building objects in the first place?

The answer to that is lengthy but I’ll try to hit the high points.  Let’s start with the act of a user entering data into the three fields to search.  This is technically an object.  It is an AccountSearch object.  It isn’t a very hard object to create, it just has three properties.  Here are the things a developer has to think about though.

  1. Searching by just pet name will return too many results.  The developer must force that users enter the pet name and the owner last name.
  2. If a user enters a phone number only, that is ok.
  3. If they enter all three fields that is ok.
  4. The phone number must be formatted correctly to match how it is stored in the database.
  5. The pet name and the owner last name much match a certain criteria (example % isn’t in anyone’s name).
  6. Who is allowed to use this object?  Can just anyone in the world use it?  Probably not.  Therefore there are security concerns as well. 
  7. How is the object bound to these fields?
  8. Is the object in a broken state (error?).
  9. Was the object modified? (in other words you can’t search on something if there is nothing there)
  10. Is the object in a valid state?

All of this needs to be thought about and leaving any one of these off can cause lots of problems within the application.  Therefore, this is why we’d have an object that handled all of this logic.  And this is why we call them “business objects”.  In this case it is a single object that encapsulates all of these scenarios.  Take the first letter in the CSLA.Net Business Framework.  The first letter stands for “Component”.  This is where the name comes from because as you can see we are dealing with a single component that accounts for all of this.

How Many Objects Are On This Screen?

Now that we’ve established our initial object model was a complete waste of time, let’s look at what we should do with this example.  Looking at my prototype example, how many business objects do you think are on that example screen?  If you said three, you’d be correct! 

image

  1. AccountSearch.cs – This object encompasses the search functionality I elaborated on previously. 
  2. AccountSearchResult.cs – This object is a Read-0nly object that simply holds the data for each row.
  3. AccountSearchResultList.cs – This object is a Read-Only-Collection of AccountSearchResult objects. 

Even though the AccountSearchResult object is just a read only object it still needs to be an object.  For example, what if the business required us to change this screen and add another column that only admins could see?  Maybe the column in this case would be a column that held the Owner’s social security number.  In this scenario, the AccountSearchResult object needs to know how to handle this situation and it should know based on the user viewing it that it is not suppose to show that property.  More times than not a developers first reaction is to put this into the UI because it is easy and they aren’t using something like CSLA.Net that provides this functionality out of the box.  Writing that business logic in the user interface doesn’t do any other developer any good if another UI is built like a web UI for example.  Again, that object needs to know how to handle this.  Think component!

What about reusability?

The next question I get after explaining this is:

Are you telling me that every screen the app has, there is a different object?

My answer is any data that is “touching the glass” of the application is encapsulated in some type of object.  In more complex scenarios that may in fact be a full blown object graph with a parent and child objects, etc.  I’m not saying don’t think of any object model but typically more complex object models are what I call core objects to an application.  In this vet application an Owner object would be a core object that would have children of pets, addresses, invoices, bills, follow ups, appointments, etc.  BUT…. ONLY IF THAT IS HOW IT IS VIEWED IN THE APPLICATION!  The difference is you have to think of the YAGNI principle which is if you ain’t gonna need it, don’t put it in your object model.  Build the object model based on the expected behavior. 

Obviously when we build objects we like to re-use them and in some cases you can.  For example why wouldn’t you be able to reuse something like an Address object?  In most cases an address is just an address.  There are cases where even something as simple as an address needs to be in a separate business object though because of the business concerns around it.  For example imagine you were building objects for a realty company.  The address of the client vs the address of the subject property being sold are COMPLETELY different objects with different business rules around them.  This is exactly what I’m talking about.

When building your application you have to think about how an object is used.  For example, take our search screen example above.  What if we were told to build a search screen with the same search fields that returned a slightly different result set.  This is the crossroads where a developer has to really think and make a decision.  Basically there are two choices.

  1. Re-use the existing result object and modify it to account for both scenarios.
  2. Build a brand new object.

There isn’t a hard and fast answer I can give you as which way you should go.  My default answer is make them different objects since later on you can easily update one without impacting the other as new changes come in.  However you may decide to keep everything in one object based on the amount of time you have.  A general rule of thumb to follow is if 80%-90% of the data and logic in the objects can be re-used, then you may decide to just update the one object.  As you approach a lower percentage of re-use you are just causing yourself problems and need to separate those concerns.

The best way to think about this is let’s say you were building a screen that returned just plain old data (not even thinking objects anymore).  And on that screen you had 5 pieces of data.  Your data query might be something like: 

select col1, col2, col3, col4, col5 from MyTable where col1 like ‘%foo%’

If someone asked you to take out the second column in a certain scenario, would you leave the query alone or rewrite it as:

select col1, col3, col4, col5 from MyTable where col1 like ‘%foo%’

I would HOPE you wouldn’t return the second column if your application didn’t need it!  Building different objects for different purposes is the same thing.  Sometimes you might choose to not modify that query.  But as more columns are changed you’d be crazy not to think about the extra payload you are putting on the database, the network, and latency being built into your application.  It is a fine line to walk but as I said, if I have another screen in my application, I’m going to automatically make another object that encompasses that object for that one given scenario.  Remember, it isn’t just as simple as returning data.  If it were, there wouldn’t be something called business logic!

For further clarification let me say this.  If both objects in my application use the same business logic I am not going to duplicate that logic in each object.  That is silly and doesn’t scale.  That logic should be moved to a common library so it can be referenced from both objects.

Takeaway

The big takeaway from this litany of verbal spillage is when you design applications you have to know how the end-user is going to use the application and what the business requirements are.  Sitting down and building an elaborate object model, while really fun and educational, it is a big waste of time.  Don’t do it.  Sit down and ask questions so the behavior and business requirements can be accounted for.  Whether you are using CSLA.Net or not the same thoughts must go into building the application.  I hope this helps cements these concepts because I know there is a large amount of disconnect with this out there among developers who think everything is a perfect object graph like they learned it in school. 

Technorati tags: , ,