One of the key precepts in home remodeling is to not move a load-bearing wall. Most frame construction houses have two types of walls: load-bearing and non-load-bearing. The non-load-bearing walls may be moved, as nothing will collapse if it is moved. This is not the case with a load-bearing wall. Moving it can have disastrous consequences.
[See the FawltyTowers episode "The Builders." ]
As we evolve our software systems we encounter the same situation. Some attributes are so important that they make up the cornerstone of the design. Unfortunately with time and continued evolution, that they are so important can become hidden.
I believe that one of the significant benefits of documenting the patterns of a system that is evolving is to train team members what are the load-bearing walls. What are the things that look trivial, yet have some far-reaching influence upon the system, and so should not be moved? Patterns help answer
-- Barefoot Joe
Do you have a RealName, please, Barefoot Joe?
How do we determine what is a LoadBearingWall
in software? Is it the parts that look trivial but aren't, or is it just the most important parts of the design? -- AndersBengtsson
If the ProgrammerTests fail when you remove it, it was load-bearing. Refactoring will be required. Perhaps one may view "replacing a LoadBearingWall with a rolled steel joist(?)" as a fairly serious refactoring of a house...
In a house, yes, but what about software? Are there any examples of anything in software that is even remotely like a load-bearing wall in software?
Could it be that the concept of LoadBearingWall is analogous to the kind of change which causes many tests to fail? Imagine a typical business application. Perhaps the use of relational storage, or the assumption of a request/response interface, or the reliance on one manufacturers stored procedure implementation (for example) are so ingrained in the application that changing them might cause many things to collapse? I'm sure we've all worked on systems like this, where some design choices have a disproportionately large impact on "shape" of the software.
If this is the case, then the analogy to applying an RSJ might be something like inserting an abstraction layer or isolation API, to hold up the application while such major assumptions are changed.
Any bug worth be called a bug will cause the software to collapse or to malfunction. So almost the entire source code of an application is "load bearing". But his does not mean, we cannot "move it". Simply change what you want to change and see whether the software collapsed. If it did, no problem, fix the bug you've introduced. Software is not a house, changing and testing is cheap. If not, make it cheap.
Any bug worth be called a bug will cause the software to collapse or to malfunction. So almost the entire source code of an application is "load bearing".
With a load-bearing wall, the house only collapses if you remove it without replacing it with some structural equivalent. To carry the analogy to software, it would be a portion of the software that, if removed and not replaced with something similar, would cause the application to not fulfill its primary function.
For example, with a text editor: file loading and saving, and inserting and deleting characters are load-bearing. Without these functions, you can't really call it a text editor. Web browsing, mail reading, and games (all present in emacs!) are not load-bearing. You can remove these and still call it a text editor.
The funny thing is that you can't put a house in stasis, or reload it from a backup house. If you don't run
the software while the load-bearing part (e.g. database access layer) is broken then it doesn't matter, nothing collapses.
Hence I suggest the analogy of software to building a space-station. Few things are actually load bearing because there's no gravity while you're doing the construction. (Perhaps before you spin the thing up? OK, and prestressed elements too, including your air tanks. Customer database?) You worry only about mass and its inertia: can we join these two very large pieces together this afternoon? they're a mile apart...
Of course if someone switches the gravity on (sends the software live) before you've got all the crossbracing struts in place it will all come crashing down round your ears. ModifyingLiveSoftwareConsideredHarmful?
, and perhaps its cousin ProgrammingInTheDebugger
In answer to the above, a non-load-bearing wall will simply fail by itself (that is, not be there) when it is removed. This is equivalent to a piece of code that, when moved or removed, breaks its UnitTest
. Once you have refactored a piece of code so that other code depends on it, it is now load-bearing: if you screw it up, you will break other pieces of software and other UnitTests
. Once you start taking the output from one piece of code and use it in another piece, the first piece becomes load-bearing: screw it up, and the other code will fail due to GarbageInGarbageOut
. Just about everything in software is load-bearing to some degree. The least load-bearing code is the output to the user, as nothing else depends on it. Fortunately, this is the code that users want to change the most--being less load-bearing, it's more flexible, where changing the core logic is more dangerous.
See also StableDependenciesPrinciple