What Makes Software Flexible

I just moved this chunk out of ExtremeProgramming, because I think the question is interesting enough to be considered separately. "Young Obi-wan, do not delude yourself into thinking that features are stable. By the time you finish that first release of three months, the features that the customer did not select for that release may not be needed anymore; or may have changed form dramatically. Indeed, it is likely that even the features within the release will change significantly. You don't want to base your architecture on things that are likely to change do you? Wouldn't you rather base your architecture on the features that the customer thought most important?" --RobertCecilMartin (reposted w/o permission)

"But, master, since the universe is illusion, to base a system on a feature is surely a mistake! The features the customer thought most important, by your own admission, are what thecustomerthought , not the Truth itself. Is it not better to base my architecture on the thing that the application is about? Observe the joy of those programs that fullfill their OneTruePurpose!" --

"Ah, but is it Truth who must be satisfied, or those who pay you? Do not lose sight of what is being attempted. We are merely trying to make something that will work, not creating art."


For a big chunk of my professional life, I've thought flexibility in software was available from various OO ideas, like AbstractClasses?, DesignByContract, and so on. These assume that the safest system change you can make is to add code rather than modify existing code. If I add a new class that conforms to an existing interface, or just uses existing interfaces, then nothing that exists is threatened.

If you believe this is important, then it seems that you'd be tempted to think ahead when designing, rather than follow YouArentGonnaNeedIt. The XP community challenges this orthodoxy, and (it seems to me) says that actually modifications need not be much more dangerous than additions. --DaveCleal

Also, if XP says that traditional OO ideas about flexibility aren't so important, then IsXpIndependentOfObjects or the traditional OO ideas about flexibility are simply wrong.


You're right that one's theory of 'safest change' is absolutely crucial here. Add or modify, the safest change is always to a system, in any language, where DoTheSimplestThingThatCouldPossiblyWork and RefactorMercilessly have been consistently previously applied. --RichardDrake

I remain unsure. The most critical piece of XP for making modifications safe is the comprehensive unit tests. For some kinds of changes that's fine, but I worry about reversing more abstract design decisions. I don't have a good example to hand, but I will think about it... -- DaveCleal


I think of flexibility as the quality which minimizes the amount of work you have to do to get from point A to an arbitrary point B; you need get rid of or avoid everything that you don't need, and then add what you do need. When you keep your system in a state where you only have to add things, it is very flexible. There is a cost to keeping around things that might, kind of, maybe will be needed someday; it is harder to see where you can put new things. The area around the code has more potential than any code you can put in its place. -- MichaelFeathers


Some colleagues and I were discussing topics like this the other day, and we came up with the following list of software characteristics that we think are typical of highly flexible systems. This is just brainstorming. But it feels at least partially right to me. The characteristics are:

  1. Simple objects
  2. Simple boundaries between objects
  3. As few of each as possible without compromising qualities 1 and 2

These are arguably so vague as to be useless, but there you go. Do these feel like the goals you're aiming toward as you build systems? --GlennVanderburg

I would add ...


WhatMakesSoftwareFlexible? Whitespace.
There are two ways to define flexible. One definition would be a measure of how easy it would be to reuse that class in a new or similar context without touching a single line of code. Another definition would be a measure of how easy it would be to increase that classes functionality so that it can be used in a new or simular context without redesign. In the former one has intentionally attempted to anticipate all possible uses, in the latter one has only addressed current requirements, but has done so in a simple and straight forward way.--DonWells


Expanding on the previous comment:

runtime flexibility (or configurability) The ability to change the functionality of the software without making code changes. Achieved through configuration data, plug-in architectures and embedded languages. No code changes need be made to the core system.

internal flexibility The code is easily adapted and extended to supply new functionality without major redesign. For instance, a flexible system would be able to have a security model added without major redesign. Is XP able to help us accomplish this?

external flexibility The software be used as a library or framework and reused (without source code changes).

We should create flexible software through extensible architectures rather than implementing many possible solutions (of imagined requirements). I guess this is just another way of saying: YouArentGonnaNeedIt.

However, isn't extensible architecture in opposition to XP until a need for a particular extensibility is required. For example, using XP, would you create a level of abstraction to your persistence layer (for extensibility - in case you need to support multiple database vendors or both RDMBS and ODBMS), or would you leave this until there is a requirement to use more than one database vendor, and then refactor like mad?

My apologies for my abuse of the English language --SteveShaw.


I'm defining flexibility as follows (is this XP'ish ?):

A system is flexible, if modifications that are known to be necessary can be locally confined.

I distinguish three cases:

1. an aspect changes for the first time: Add the change and ReFactor the system as to eliminate any code duplication the change might have caused (OnceAndOnlyOnce). This will likely create a new VariationPoint?.

2. an aspect changes for the second (third ...) time: If an appropriate VariationPoint? does already exist, just add the new variant. Otherwise, ReFactor to create one (similar to 1.)

3. an aspect might change: Then you YouArentGonnaNeedIt right now.

There are lots of different possibilities for defining a VariationPoint?, from case-statements to abstract base classes to reflective systems. The most appropriate solution depends on the particular change and context. Thus, flexibility is in no way specific to OO nor is OO required.


Can flexibility be considered independent of the flexor? Perhaps one programmer's flexibility is another programmer's straight jacket. Can you think of an example?

Sure. What about the frameworks in this book [1]. The authors claimed a good deal of flexibility for their various results. But I imagine there are those who would, from personal experience, claim the opposite.


I always find it's best to CodeDefensively? and CodeForTheMaintainer. This can add some cruft like the VirtualStaticIdiom, but it makes extending the system very fast, easy and less errorprone.

YouArentGonnaNeedIt suggests otherwise. I don't know. A little bit now can go a long way later. -- SunirShah?

By the way, I've realized that the code first then refactor method isn't for me. It's far too bottom up, which means I have to throw out all my other problem solving heuristics. It seems like I'm jumping into a box instead of excaping from one. Bend like a willow.. keep flexible.

I am now experimenting with solving software systems one problem at a time, however. I believe deeply in microiterations. --ss


Tools and language make a difference. If our language or the way our files interdepend are deeply resistant to refactoring, then more investment up front is perhaps more valuable. In general, money spent on tomorrow instead of on building what we need today is inherently wasted. It's putting money in the savings account instead of buying food. There is a chance of earning it back tomorrow, if the product survives, and if we need what we foresaw we might, and if it really costs less, and other ifs. If there were no other way, we'd have to make investments in the future. But there is another way: clean code, refactored as needed. --RonJeffries


Being back into the theoretical stream of things, I've reconsidered slightly. My new answer is indirection. We know that from programming (PolymorphismVsSelectionIdiom, for instance), so let's apply that lesson to a metalevel. The system and the definition of the system are disjoint, giving us another level of indirection. So software systems are flexible to change because we can get at it at a higher layer. And naturally indirection makes for flexiblity because it allows you to defer decisions to much later, or even change decisions. Conversely, if we put all systems onto IC chips, then the system and logic are identical and inflexible. It's that Turing guy again. -- SunirShah?


EditText of this page (last edited July 26, 2001)
FindPage by browsing or searching

This page mirrored in WikiPagesAboutRefactoring as of July 17, 2004