Business-Object-Oriented Development (plus ramblings on best practices and annoyances by a madcap programmer with poor memory)
View Article  Simple Exception Handling

I think any developer with any amount of experience would agree that one thing you do not skip, rule-bend, or even do poorly is exception handling. I would add that it can be tough to justify complicating error handling by turning it into its own subsystem with a bevy of objects and possibilities.

 

For what it’s worth (I guess I could stamp that across every blog entry) here are my bare-minimum-yet-good-enough-for-most-common-business-application-development exception handling rules:  Do it, Be consistent, Keep it simple, Throw in the kitchen sink, Roll your own, Always at initial point of action

 

Do it

Like I said before, this is nonnegotiable, you use exception handling.

Be consistent

Be consistent across the solution. Everyone working on the project knows the simple rules and follows them in the same way.

Keep it simple

The simpler it is the more likely everyone will do it and be consistent. Make people justify any specialized exceptions.

Throw in the kitchen sink

Throw exceptions with every bit of data that could possibly be available to help the coder determine what happened.

Roll your own

Don’t call Parse on a type and let the code throw a “wrong format” exception, rather call TryParse and then throw in the kitchen sink when it does not work.

Always at initial point of action

Catch and handle exceptions at the initial point in the application where the system is sprung into action. In the common business application, this is often behind a button click or some other event handler for a user control. In other words, when a process (no matter how small) kicks off, wrap the call in a try-catch block and handle any exception gracefully. I often tell people that the only code in an event handler for a user control should be a try-catch block with a call to the action’s handler.

private void btnAddFileToRelease_Click(object sender, EventArgs e)

{

  try

  {

     TryAddingFileToRelease();

  }

  catch (Exception ex)

  {

    HandleExcpetion(ex);

  }

}

  

Notes

Unlike the old days, most modern programming environments provide a full call stack in an exception, so we know exactly where the routine bombed. Because of this we often don’t need exception handling all over the place. We need it at the initial point of action so our application stops gracefully and we need it when objects must be disposed.

 

Creating custom exceptions: Some coders seem to do this for every new exception they think of, often inheriting some base exception. This is poor OO programming to begin with even though it might look cool. A generic exception with a message that explains the unique error will suffice in 99% of the cases. Like many things I vote to keep exception handling simple before it turns into a subsystem all to itself that the next guy has to comprehend and maintain. Create a special type of exception if the code will behave differently because of the type. For example, if an exception is a network down exception, then the code might try again n number of times.

 

Simple Exceptions: Often code “knows” the context of a call and thus might know that a user could fix the issue. In this case a special Simple Exception could be thrown. When the exception reaches the client interface the exception could be handled differently. Instead of logging the error and emailing support, a simple message could be displayed to the user allowing them to fix the issue before trying something again.

For example, a system may allow users to define Widget Types and import Widgets into the system. During an import a Widget Type Key is read and the system looks up the Widget Type using they key. The code that does this could throw a Simple Exception if the Widget Type is not found.  The user would then get the message, set up the new type, and try the import again.

Just make sure your assumptions about whether or not the issue is user-addressable are valid. Often these assumptions that lead to Simple Exceptions being thrown are low on the call stack and not deep in the bowels of the system. Furthermore, Simple Exceptions are useful when you do not want to provide a list of issues for the user to address. Simple Exceptions also simplify process code since the number of conditional statements is greatly reduced. Instead of if x=true then [add issue], else continue we just have ThrowSimpleExceptionIfTrue(x).

View Article  How do you start?
In the past year or so I have answered questions or had conversations with developers about the steps I take or path I follow from start to finish when writing an application. I tend to dodge this question by essentially saying that it depends on way too many things to answer.  However, I have realized that this is a copout. If someone asked me how I got home from work, I would not tell them it depends on way too many factors to answer definitively. Rather, I would describe to them what you might call my default path, and it would be understood that hundreds of “what if” situations could cause me to alter my path. What if you are in a hurry, what if traffic is backed up, what if it is snowing, what if it rained all day and flooded the river bottoms by your house, what if, what if, what if? 

 

So I decided I would list my default path here regardless of the type of application, with no preconceived notions, and I’ll try my best to not say “if” or “it depends.”

  • Take rough notes as I have high-level discussions about the business and the software the stakeholders are dreaming about for that business.
  • Explain up front my expectations for the design and implementation of the software (Stakeholders constantly design with me, standardized language, evolving software, building simplest thing that works with solid design that allows easier change, upgrades, and maintenance).
  • Get a high-level summary from everyone involved regarding accessibility, maintenance, support, performance, environmental constraints, etc as much as deemed needed. Still at a rather high level. Just write something down as a bare minimum.
  • If the system replaces an existing application or manual process, observe the users.
  • Identify subsystems as discussions about the overall system get more detailed.
  • Work with everyone involved to define the simplest subsystems that could be built that provide value. This results in requirements and the identification of  bells and whistles, requirement priorities, etc.
  • Flesh out the requirements for the simplest-thing-we-could-build-that-provides-value by producing use cases, user stories, scenarios, pictures on whiteboards, napkin drawings, etc.
  • At every point after the initial conversation update a domain model of the objects involved and make sure it is available to everyone.
  • Identify the most interesting, difficult, and/or risky business logic.
  • Start producing the software, letting the user stories and testing drive the design of our objects and their responsibilities
  • Observe users using software to see how the software is actually getting used and then make necessary adjustments.
  • Create documentation for the most interesting, difficult, or risky business logic and how the domain objects and services will complete a need. Make sure to note any design decisions that involved any lengthy discussion or back and forth comparisons.
  • Address storage concerns for any data that requires permanent storage, and dynamic data needed for easy configuration
  • Refactor anything that smells (really done along the way as tests are written and run)
  • Rinse and Repeat
View Article  Nullable Columns - To null or not to null, that is the question...

Google “nullable fields”, “nullable columns”, or “null debate” and you can read about people arguing about whether nullable columns in a database table are evil and are slower to process (among other topics that hold no real interest for me).  I want practical rules-of-thumb when I am in a situation where I think I might need a nullable column.  What issues can they cause for me as the developer of the common business application?

 

For me, a nullable column is a design scent, not quite a design smell, but I am starting to get a whiff of something that might not be pleasant. Often the nullable column is justifiable, other times I would argue it is not. Like any design decision there are many, many factors that can justify or condemn a nullable column.

 

I present here my most basic rules-of-thumb when deciding what to do with a possible nullable column. If the business significance of the entity in question is great, then these basic rules-of-thumb might be too basic. That said, often these heuristics are all I need.

  • If nothing governs the nullable field of the entity then it’s OK
  • If one attribute of the entity affects the nullability of another then I might give this nullable attribute a little more thought.
  • If one attribute of the entity affects the nullability of multiple other fields then it’s probably not OK

If nothing governs the nullable field of the entity then it’s OK

The middle name attribute on a person name entity is a good example of this. There is nothing about the entity that dictates whether or not the middle name attribute is null or not. We just have the data, or we don’t.

 

If one attribute of the entity affects the nullability of another then I might give this nullable attribute a little more thought.

We might have an address entity that has a Boolean attribute IsUSA and when this attribute is true then postal code is required. This is OK, but it would start discussions on whether or not we have two entities (Domestic and Foreign Address).

 

If one attribute of the entity affects the nullability of multiple other fields then its probably not OK

We are most certainly missing an entity when we find ourselves in this situation and are representing two or more entities in one table. Either we have different base entities or the multiple attributes are describing different entities that are related to the base entity. Our model loses clarity. We have to acknowledge that we are representing more than one entity and understand the benefits and drawbacks.

Example of two different base entities in single table: Security Entity (ID, Name, Security Type, Comment, BData1, BData2)

When Security Type is Bond then the BData1 and 2 attributes have to be filled in. We should acknowledge that we have two entities, a Security and a Bond.  This model does not make it clear that there even is such thing as a Bond and that only it uses the BData 1 and 2 attributes.  It appears that a Bond is a Security so they share some base data (ID, Name, Security Type, and Comment).

Example of one entity with relationship to multiple entities in single table

Contract Entity (ID, Name, Code, DataA1, DataA2, DataB1, etc)

When Code=A then DataA1 and DataA2 need to be filled in. When Code=B then DataB1 needs to be filled in, etc, etc. In this example we don’t have two base entities, we still have only one kind of Contract. However, the Contracts are associated with Code Specifications that are not modeled in our design. ContractEntity(ID, Name, Code) CodeASpec(Code, Data1, Data2) CodeBSpec(Code, Data1), etc.

 

 

The practical benefits and drawbacks to representing multiple entities in one table

Benefits

  • Combining the entities into one may be exactly how the system consumes the information in the table. For example, we may find that the table is never queried alone and the other tables are always joined in which complicates the data consumption.
  • Entering data requires going to one table which is a benefit if data entry is being done by hand and the data entry person benefits from seeing all the attributes possible.

Drawbacks

  • When multiple entities are represented in one table we suffer the standard drawbacks of not separating our concerns which should be a basic credo for every developer.
  • If another table requires a foreign key into the table in question but only for the records of one of the entities then referential integrity gets pretty complicated
  • Lack of clarity in our model as to what entities exist.
  • Lack of clarity in our model as to why a null exists. Is it because we don’t have the data or because the data is not required to be there?
  • If the multiple entities are ever consumed as separate entities then we complicate things by separating the entities in stored procedures and or code.
  • General logic and joins with nullable fields are more error prone
  • Referential integrity is made more complex by the need for triggers and or constraints to be written and maintained for the one table managing multiple entities.
  • Possible sign the model has frozen and the system is no longer evolving but rather being hacked just to get work done. Often a table evolves into storing data for more than one entity and when we don't address it we often start to suffer the broken window syndrome.
  • A system with multiple entities in single tables often cannot be extended without change. Instead of adding a new table for more functionality we end up editing existing tables and their constraints, possibly breaking existing functionality. (Granted this is tied to separating our concerns.)

 

Interesting Note

It can appear that putting multiple entities in one table is breaking data normalization, specifically third normal form.  The third form of normalization states that all data is dependent on the primary key. In the case of nullable columns that are dependent on a value outside of the primary key we might figure we have broken normalization.  However, the rule is about attributes on an entity that don’t tie back to the primary key but rather another attribute in the table. The attributes we have been talking about are attributable back to the primary key.

View Article  Your object-oriented program is not object-oriented

You expose the data behind your classes because you don't want to do what needs to be done in order to keep it encapsulated. Admit it.

 

No one I know (including me) implements a pure OO solution for the common business application, and if you think you do, you are probably wrong. Author and Java-geek Allen Holub does, but technically I don't know him. I have always been a fan of object-oriented techniques and was easily won over by its simplification of complex elements. However, I have always struggled with how it applies to the common business application and have not been happy with many of the implementations I have witnessed and/or were a part of in the past 10 years. I think only recently I have come to accept I will not be happy with the drawbacks of a pure OO business application and I have to rely on and be content with something in between pure OO and procedural development. 

 

There are two needs in a common business application in regards to the data that exists behind the business objects.

  1. The need to derive business answers based on business rules that require the data
  2. The need to manipulate that data and have those changes reflected in permanent storage as both part of a business course of action and at the whim of an administrator
These two needs nearly always conflict with each other.  If we only had to concern ourselves with the first need I would contend that every single OO heuristic and OO pattern would be easy to implement. However, OO heuristics get marginalized and business object designs utilizing OO patterns get hosed and hacked simply because we have to deal with the second need.

 

A clear example of this conflict involves editing a business entity.  Let’s say we have a well-designed business object called User with all its data encapsulated and exposing a single method called CanAccessBeGranted. A system administrator wants to look at a particular user on a Windows GUI for the purpose of changing some information. Obviously we don't want to break encapsulation as it is a cornerstone of object-oriented programming. So how does the GUI display all the information related to a user if the user object cannot expose all its data without sacrificing encapsulation?

 

What are our options, and what are the benefits and drawbacks of each?

To be clear the objects in question are business objects from the middle layers of an application.

 

The objects can display themselves

Methods could be added to the classes to display themselves on whatever mediums the objects needs to be seen on.  This is the purest OO solution to the problem. It matches the standard rule: Don't ask for the information you need to do the work; ask the object that has the information to do the work for you. In other words, don’t ask the object for all its data so you can display the data on a GUI, rather ask the object to display itself on your GUI.

This solution is the norm for programs like games and other GUI-centric applications such as drawing programs and word processors. Want proof, see the seminal book Design Patterns (Gamma, et al) and take notice of every single example aside from maybe the Creational Patterns. The objects involved are not those of the common business application, they are not business entities represented in software.

Benefits

  • Total encapsulation is maintained.
  • Single place for implementing change. When an object's display needs change we don’t have to go to every UI to fix it, we just change the one class.
  • Allows for the use of many standard patterns that often cannot work when data is exposed.

Drawbacks

  • Makes business objects dependent on one or more user interfaces, or at a minimum user interface technology.
  • User interfaces and the interaction that goes on can be complicated enough without having objects navigate their space on a form and manage their interactions with other objects on the fly.
  • Makes objects concerned with more than just their business logic.
  • Assumes the same developer or developers with the same skill sets are responsible for an application’s appearance and for the application’s behavior.
 

Publicly expose all object data

Every attribute is exposed so a GUI can display each property as needed and the way it prefers. This is the absolute furthest from an OO solution to the problem and is a case of throwing the baby out with the bathwater. Unfortunately this is what many developers do, leading to procedural applications with anemic domain models.

Benefits

  • Data is easily accessible to UI

Drawbacks

  • Data is easily accessible to UI and any other code that wants to use it. We can Google encapsulation or read any OO books to learn all about the fragile nature of applications written this way
  • Relies on a convention to enforce that exposed data is never used for anything other than viewing. The convention is very easy to break
  • Many useful OO techniques like abstract classes often cannot be used since clients working with abstract classes cannot access the attributes of the concrete classes when they differ 

Expose data judiciously and indirectly

All data is kept private until it is proven it needs to be internal/friend and only made public when no other option is feasible. These other options include exposing a display string that uniquely identifies an object on a GUI or a summary/description/report string that lists multiple properties in paragraph or list form.

Benefits

  • Just requiring that a thought process be exercised before exposing data can cut down on the number of publicly exposed object attributes
  • Exposing string descriptions can often suffice instead of multiple properties being exposed and concatenated on GUIs and reports. This makes it much harder for developers to misplace logic

Drawbacks

  • A lot of data gets un-encapsulated in a system with normal maintenance requirements which leads to all the same drawbacks incurred when exposing all data.
  • The chosen display properties don't satisfy UI developers wishes to have more control of every property.
 

Use a second object to expose the data

All data is kept private. When information about a business object is required because it needs to be viewed and or edited on a GUI then the business object exposes a second object that allows access to the data. For lack of a better term, I will refer to this as the Data View object pattern.

Benefits

  • Abstract classes can be used as the “data view” object can be the same for all concrete classes with possible optional attributes.
  • Makes the convention that exposed data should only be used for viewing more apparent and harder to break because of the indirection required to get at the data
  • Lends itself to the candidate object pattern where this secondary object can be responsible for authenticating new or changed data. This validation code is always needed and this object gives it an OO-suitable place to live.

Drawbacks

  • Gives a business object another concern besides its business (creating a view object of itself)
  • The data is still publicly exposed even if just indirectly
 

Use an interface to expose the data

Private data is exposed only via an explicit interface. The business object would have a view property that returned the viewable interface to the object.

Benefits

  • Makes the convention that exposed data should never be used for anything but viewing more apparent and harder to break because of the indirection required to get at the data. The protection is weaker than a separate object, but it does provide a road bump that can make developers slow down and think about what they are doing. It also is pretty easy to see in a code review: if myWidget.View.Status = ...wait a second, Views should not show up in business code!

Drawbacks

  • The business object is a bit more complex as its attributes are all assigned to one or more interfaces
  • When the business class is an abstract class it will get very messy trying to wire it up with interfaces that will reflect the possible concrete classes
  • The data is still publicly exposed even if just indirectly
 

Graphical Subsystem like Microsoft’s WPF

I have limited knowledge and no experience with these types of subsystems, but what I  understand is that essentially a class could just describe its layout using XML and then any front end that understands that XML could render the graphics.

Benefit

  • The type of user interface being displayed on is abstracted away from the business object.
  • Would assume you could use a graphic interface to help develop the user interface and then move the XML to the object which makes this solution easier than custom coding how a object will display itself
  • Keeps the data encapsulated

Drawbacks

  • All the same listed for object’s displaying themselves, though the coupling to GUI technology is lessened.
  • Requires framework knowledge beyond just the language to maintain

Create Separate Applications

Business objects and the objects created for viewing and editing data are completely separated into different applications.

Benefits

  • There are no cross cutting concerns when the need to view and edit data is completely separated from the need to do business with entities.
  • When two groups are responsible for these two needs, there is no need for agreement between the groups on what objects are needed and how and when data is exposed.
  • Development of code for two separate needs can easily be done in parallel

Drawbacks

  • No reuse of code in the same domain
  • Possible lack of ubiquitous language for the users of the system
 

What do I do?

As always, I am in the middle. I have a hard time subscribing to the objects-display-themselves technique for the common business application, and I really don’t want to give up on OO heuristics as with the expose-everything solution. So I use a combination of the aforementioned techniques. But I think most importantly, no data is exposed by default except for identifying attributes (Names, Descriptions, Keys).  The importance of logic staying with the data in a class is drilled into anyone's head who works on the same project.  Whether or not coders retrieve data from an object always comes down to convention, as in rules that cannot be enforced by the compiler but only by coders themselves.  The size of the team, the OO-awareness of the developers, and other factors might dictate how well your conventions are followed.