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
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.
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
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
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?
PingBack from http://www.basketballs-sports.info/basketball-chat/?p=1287
Nice post. My biggest pain points in the past have been around deployment. If you can't prove that your deployment strategy is valid, you might have already failed. You just don't know it yet.
Last post I was thinking about change and how one plans for change in the life of an application.
This paper is often quoted, but not often read:
David Parnas: On the Criteria To Be Used in Decomposing Systems into Modules
You've done a good job of hitting near its heart. I can't recommend a read/reread enough. :-)
"We have tried to demonstrate by these examples that it is almost always incorrect to begin the decomposition of a system into modules on the basis of a flowchart.
We propose instead that one begins with a list of difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others. Since, in most cases,
design decisions transcend time of execution, modules will not correspond to steps in the processing. To achieve an efficient implementation we must abandon
the assumption that a module is one or more subroutines, and instead allow subroutines and programs to be assembled collections of code from various modules."
Functional Decomposition: 0
Design for Change: +2
Many of the OOP principles I design with have this at their heart (single responsibility principle, open/closed principle, etc).
One of the most interesting things is how designing for change also affects comprehensibility (in a positive way).