Wednesday, June 15, 2005

Versioning

Why is versioning of shared objects so difficult? By shared objects I'm including DLLs, .sos, COM/DCOM/CORBA Objects, and Web Services. Should it be difficult? If so, what parts? What are the issues that can arise? Why are new shared objects released? These questions are the ones we'll examine in this blog entry.

First, let's start at the beginning. Why are new shared objects released? Lets try to enumerate:
  • Bug fixes - These are changes that should change an improperly behaving object into a properly behaving object while not modifying any otherwise functioning behavior.
  • New method - All old behavior is retained. New behavior is also added through new messages.
  • Modification of functionality - The old functionality is now (or perhaps always has been) inappropriate. Therefore, new functionality must be introduced to replace it. This could exist due to legal issues or contractual issues. However, no interfaces change.
  • Modification of interface - For this to occur, all messages still exist, but one or more messages require different information. This could also occur for legal or contractural reasons. For instance, a field previously provided by a data provider may no longer be available or the length of a field may have changed.
  • Removal of functionality - Sometimes it is necessary to remove functionality that has been deprecated or that is no longer appropriate.

Some of these reasons should not require the clients to change at all. Some may force the clients to change. Finally, some changes may not require a client to change, but may mysteriously fail if they don't. In the above enumeration, a bug fix and a new method should not require old clients to change. However, sometimes clients depend on certain bugs and removing them may not be as easy as you would hope. Modification of interface and removal of functionality may fall into the second category: requiring the client to change. If a client uses one of the modified or removed messages, then the client should fail to run, period; otherwise, the client should continue to run as if nothing has changed. However, modification of interface may not require a change if the interface is sufficiently generic. Modification of functionality is the most dangerous of the modifications. With it, clients may unexpectedly fail for no good reason. Furthermore, it is difficult to know which clients may be affected and which ones won't.

To me, it should be difficult to release changes that adversely affect the client. Interface changes that are not backwards compatible should not be released - instead new methods should be added. What is the difference? Clients will have to be modified either way; with a new method then the old clients are still runnable. Furthermore, subtle changes that cause clients to mysteriously fail should be avoided AT ALL COSTS.

Next time, we'll look at some solutions to these problems and try to go outside the box to find the best way to release shared objects.

No comments: