Tuesday, July 15, 2014

Planning for change

Today I had to implement a change across many applications that were all in different states of organization. I saw several different styles of coding and architectural styles. Some applications required minimal changes, others required some core changes that were deferred due to timing of other projects. The main issue with the ones that required more work were that they were written under the assumption that the way it was will be the way it will always be. What? Let's parse that out.

It was a certain way when the application was built.

The developers assumed at the time that this is the way it will always be.

This could not have been solely the developers' doing though. Often the business will make the assumptions for the developers and not even deliver a possibility that they will change in the future. But there may be some hope for developers in determining when something can change right before our very eyes!

If it's possible to change, then assume that it will.One thing that can and does change all the time is the name of things. If something can be called by an id or a name it's likely that the name will change. This is one big smell that we can be aware of that should call to mind "can this change?".

Once we have identified that it can change, the next step is to analyze the impact of the change when weighed against the development time involved in making our code handle this possibility up front.

Here is one very common scenario and an uncommon but potentially problematic possibility where changes could have an impact:

Person
{
InternalID,
SocialSecurityNumber,
Name,
Gender,
}

Names change all the time. Gender, not so often - but it is possible. How often do we plan for a gender change edge case? Often it is assumed that it will always remain the same, but just recently I was involved in an application where the planners assumed that it would never change. There will certainly be issues if it does.

I would also assume that a social security number can change, would never use that as an internal ID unless you want to end up allocating things to the wrong person someday.

How about some type names?

ThingTypes
{
ThingTypeID,
ThingTypeName
}

then these are used in the application like so:

Big Thing is allocated to: John Smith
Wierd Thing is allocated to: Jennifer Blah
Foo Thing is allocated to: Phil Vuollet

where someone got it in their head that they want to display these distinct types of things on the page and someone else ran with that and went ahead and wrote some code that did just that:

routine:
 add "Big Thing is allocated to: {person}" to page where person := some database function to look up the person with id = 1
 add "Wierd Thing is allocated to: {person}" to page where person := some database function to look up the person with id = 2
 add "Foo Thing is allocated to: {person}" to page where person := some database function to look up the person with id = 3

so now we have some hard-coded stuff to deal with here. I got into the habit of creating data that represents this type of thing with a property called DisplayText. This makes it evident that the value is meant to be displayed and that is its only purpose. It's also a safe bet to put in a property called LookupCode, ShortCode or something similar. Usually the business will have some acronym that they will want to use in places and will refer to the entity as such in most cases. Whatever you do don't put in something vague like Name or Description (that one especially is a big offender). DescriptiveText might be better. If the text is meant to be displayed then use DescriptiveHelpText or DisplayDescription, or some name that conveys meaning.

Even better, use the same naming convention throughout your application! if you do, then you can create a reusable code bit that can do the displaying for you!

GetListValues(entityName, filter)

then you can map the properties to a generic view model that can be used to hook into a view on the page.

ListItemViewModel
{
  ID,
  DisplayText,
  HelpText
}

This can be extended if necessary through inheritence:

SensitiveListItemViewModel : ListItemViewModel
{
  SensitivityLevel,
}

Notice that the SensitivityLevel is a type in and of itself since this can change and often will.This should be maintained in the same fashion in terms of data structure and coding dynamically with change in mind.

We have seen that by keeping change in mind, and by weighing the initial cost vs long-term update costs (sweeping changes, testing effort, deployment effort included) we can recognize and plan for the future changes that will inevitably come.

No comments:

Post a Comment