Changing Interfaces Is Expensive

In my discussions with WardAndKent, a key basis for XP keeps showing up, namely that according to the normal view of things, ChangingInterfacesIsExpensive. If that is true, then of course you set up your design process to avoid changing interfaces, as most of us were taught to do (weren't you taught ChangingInterfacesIsExpensive?) . WardAndKent questioned this assumption and asked - suppose we could make it not expensive to change interfaces, then what benefits would accrue? Answer: all those things Kent keeps talking about, having to do with learning and improving and reducing design entropy. Well, if it hurts to work under one set of assumptions, and it is beneficial to work under the opposite, then find a way to work under the opposite... presto, XP with RefactorMercilessly.

But if for you, ChangingInterfacesIsExpensive, in real life, then RefactorMercilessly suffers (as do you). That doesn't touch some parts of XP, such as PairProgramming, communication, listening, UnitTests, etc.

One way to investigate the applicability of XP is to stretch yourself on the question - How could we make it inexpensive to change interfaces? (I find it interesting viewing the XP practices in this light - close knit team, seating proximity, rotating duty, absence of documentation, UnitTests, ...). -- AlistairCockburn


Changing interfaces can be expensive (or inexpensive) in several ways.

Within the context of self-contained development (within source code you have complete control over), there's the expense that if you change a feature of an interface you have to change all the uses (and implementations) of that feature, then rebuild the changed code. In explicitly-typed environments it's common to set things up so that changing the interface results in recompiling the code that uses that interface, which will detect many cases where the old usage hasn't been updated -- possibly at the expense of recompiling code which depends on features of the interface which haven't changed. For large projects the latter issue can make physical architecture an important consideration in such an environment, but internal interface changes can be managed.

What becomes more expensive is when interfaces leave the self-containment boundary. This can be in a distributed environment, where the program you build here today may need to talk to an instance of itself built there yesterday, or released last (or next) year. This is still to a degree internal and self-contained (it's not a published interface as such), but at the very least you have to "simultaneously" rebuild all the instances. Then of course there are published interfaces, for instance the API you release and document for your customers (or the one your vendor supplies to you). Changing such an interface can be quite expensive. (But so can not changing it: if your internal architecture, implemented in your favorite malleable language system, evolves away from your external base, that in itself becomes a maintenance problem).

There is a continuum here: expense should not deter you from changing interfaces which need to be changed, but changing code always has some cost and interfaces shouldn't be changed gratuitously. To me this would never argue against RefactorMercilessly (though it may somewhat influence the quality of mercy), but instead argues for a degree of DesignBeforeCoding appropriate to the circumstances.

I haven't been able to form an opinion on just what is necessary to qualify as XP as opposed to something else (ExtremeProgrammingBoundaryConditions tries to formulate cases where XP is not applicable, which is slightly different). Looking around I see some discussion of it in AreYouDoingXp?, which I hadn't seen before, but I still don't see a conclusion. -- JimPerry


Extending interfaces doesn't have to be expensive, at least not with a compiled object-oriented language with support for defaulted method arguments. One prerequisite is to be working with all the source you need, so that changes can be safely propagated (and tested). You also need to consider the backward compatibility of the new extensions. New methods shouldn't upset old methods. New arguments to old methods should have a default value which causes the method to behave the same as before. -- ScottJohnston


Re-writing an interface, changing critical features, need not be expensive, so long as you have an editor that can help you track down everywhere that needs changing to match, and so long as that change does not entail a lot of work at each location needing updating. (That is, if you're changing the type of a simple variable, that's probably ok, we can reduce that. If you're going from a simple variable to a complex structure, and need to write a huge gob of code at each use, that's... that's just plain wrong. Doctor, it hurts when I do this.) Now all we need is for someone to port that wonderful refactoring smalltalk environment to work with vi & emacs. ;> I'd take the vim port, but my TODO list currently extends beyond this three-week iteration... -- EdGrimm


There is a big difference between an interface you own and one you don't. That is, if I change this interface, do I need to notify anyone. If so, you can use a strategy like deprecation to still change the interface. The time scale of the deprecation depends on how tightly coupled the developers are. For big pools of external customers you might have to maintain a deprecated interface for months or years. For geographically separated development, it might be days (this is how they do it at OTI).

However, interface decisions are no more immune to mistakes than implementation decisions, and often have greater leverage when they are made better. The question is not whether you can refactor interfaces, the question is how to manage it. I personally like "Rename...", "Add Parameter...", and "Remove Parameter" as menu items, but then I work in a dream world.

-- KentBeck


When you change the interface to an object and that change has to be sent to developers on other projects, how would you send those changes in order to help the XP-ness of the other projects... would you send the changes as a set or refactorings followed by a set of enhancements? Then the other developers can first modify their projects to have their current behavior but refactored, and then they can add the enhancements to get the new features?

-- PatrickLogan

But isn't that precisely the point of deprecating old interfaces? The old code still works, but there is a warning that it will have to be refactored to fit the new way of doing things. -- RussellGold


In COM projects with interface users outside my "team," I maintain backward compatibility by supporting both old and new interfaces. (Refactoring changed the interface from "old" to "new.") Then I tell my customers that the old interface is "depreciated," and that they have "X" amount of time to upgrade to the new interface, because the old interface will go away after that.

After time "X" goes by, I do my best to drop the old interface. Some people drag their feet, play politics, and other nasty stuff, but eventually we'll get over those problems and get rid of the old interface. ;->

-- JeffGrigg


CategoryRefactoring


EditText of this page (last edited July 21, 2007) or FindPage with title or text search