Living through "The Change"

Funny how it happens, but things change don't they?  Our applications, as perfect as they are when brand new, grow and change over time and like teenagers, sometimes these changes are quite painful.

Over the past few weeks we have been speaking to customers about their dreams and wishes for our children (WCF and WF).  These youngsters are just toddlers really but we all have high hopes for them.  One thing we heard repeatedly and loudly from you was that you need help with versioning and some said that we put no thought at all into this.

As I thought back about my past years at Microsoft I realized that for the most part you are correct.  Even though every app will have to live through a change, we platform builders give precious little thought to how we can help you live through this.  I recall the experience of COM+ where we added a feature to disable a COM+ app to COM+ 1.5 because customers pointed out that there was no reliable way to change the dlls associated with the app without actually unplugging the network cable.  How do you build a platform and have nobody actually think of such things?

In fact, if you are building an application, you should be planning for a change as well.  It seems to me there are several types of changes that we need to consider.

Add Something New

Your app is running along just fine, working the way it should when someone asks you to add something.  None of the existing functionality will be changed, just some new "stuff" will be added to it.  This should be the easiest type of change.  It involves the following steps

  1. Build the new functionality
  2. Test new and old together to make sure nothing breaks
  3. Test the deployment in a simulated production environment
  4. Deploy application with minimal disruption to production system

Of course, the simplest way to deploy an application is to shut everything down, deploy it, and bring it back up.  My guess is that this is the most common method of deployment of applications, with the second most common being to bring one node of a production cluster at a time down while the others keep operating.

Change Something That Already Exists

Your app is running but there is a problem.  It might be a bug, or it might be some missing functionality that somebody needs.  The solution is to change the app in some way.  It might involve a simple bug fix or something as radical as a complete redesign of the internal implementation.  I am not speaking of replacing an old system which is in my view something else entirely.  This type of change is more difficult but here is what you must do.

  1. Make the change
  2. Test the change (unit or functional testing)
  3. Do integration testing with every other system that integrates with this one to insure that no previously working integration is broken
  4. If the change affects the user experience in some way, document the changes, do user testing and plan for training and increased support needs during change rollout.
  5. Create a deployment strategy and test it in a simulated production environment
  6. Deploy the application with minimal disruption

Remove Something The Already Exists

Some portion of your application functionality is going to be deprecated.  You want to remove some useless appendage of data or functionality.  Like an appendix, the easiest thing to do is to leave it alone if it isn't causing a problem.  However, if you must remove it you will need to do the following

  1. Analyze the effect of removing the thing especially with regard to historical data and reporting and user experience (are people using that thing for some purpose you are unaware of?)
  2. Remove the thing
  3. Test the app thoroughly to determine if the missing thing is going to cause a problem
  4. Do integration testing with every other system that integrates with this one to determine if the missing thing will cause an integration problem
  5. If the change affects the user experience in some way, document the changes, do user testing and plan for training and increased support needs during change rollout.
  6. Create a deployment strategy and test it in a simulated production environment
  7. Deploy the application with minimal disruption

Summary

Wow, in the process of thinking about this thing called change my thinking is evolving already.  Someone who is likely to successfully change an application will probably have the following traits

  • They have developed their application with high test coverage (TDD anyone?)
  • They have a well defined integration boundary with the app by providing integration "contracts" not only with web service endpoints but also for data integration via files or ETL type integrations.  This makes it possible for them to test the integration to determine if the integration contract is broken in some way.
  • They have a planned deployment strategy from the very beginning and are able to test it in a simulated production environment (including data)

Now some of you should be screaming at me at this point because I have neglected one very large topic.  That is the topic of state.

Applications consist of behavior and state.  If you plan only for changes to behavior but neglect to deal with changes in state you are asking for trouble.  If your application consists solely of data that lives for milliseconds and only in memory you probably don't have to worry much about this but most applications consist of state that is created, modified, reported on and archived over a long period of time.  Changes to the behavior of the code that touches this state must be considered.  I'll save that for my next post...

What do you think?

Where are your big pain points with versioning?