July 2010 - Posts
The S in the SOLID principles is one of the most simple and most important principles.
Let's take a simple example, one of a clock. A clock might have lot's of parts, parts that keep time, that tell you what the hour and minute of the day are etc.
A clock might also have other parts such a display to output the time. In OO the display would inherit the other clock parts to obtain the time and then display it. In an analouge clock this might include the clock face, hour hands, minute hands etc. In a digital clock this might include an LED display etc.
Now we ask the question while both displays are are concerned with the display of the time, the analouge clock is not concerned with the digital clocks LED display and the digital clock is not concerned with the analouge clocks hour and minute hands etc. Each display is concerned only with it's own display types and does not need to know nor bother with anything else. Both displays are not concerned with keeping the time, that is left to other parts of the clock, the only thing the display is concerned with is showing you the time.
If an LED display was concerned with clock hands it would break the SRP principle.
If we take this back to your coding we apply the SRP principle to everything from class to method, making sure that each is focused on one thing.
Technical Debt is subject that is very close to my heart, I first heard of the concept at a great session that Gary Short gave and ever since I have found ways of finding and addressing the problem. So what is Technical Debt?
Technical Debt is a like any other kind of debt.
Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite... The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation, OO or otherwise. - Ward Cunningham.
So what causes Technical Debt, for that I'am going to borrow Martin Fowlers great quadrant diagram.
Every hack, work around, bad piece of code builds technical debt. So what it is the cost, an image from this great article sums it up well.
The real cost of Technical Debt is that for every bad piece of code, it can cause problems to your customers and cost you and your business money. It can cause you defects (and in some cases) cost the business money. It can takes other coders time to find and fix the problems or work with the code, time is money.
As time goes by and theh debt builds up the cost also goes up, the further the problems, the harder to resolve and the bigger the cost.
I'll move into approaches to resolving technical debt in later posts.
Uncle Bob outlines this concept well in in the 97 rules book.
Leave the code a little cleaner than you found it
In other words where you can improve and make better the code you are working in. In legacy code you should follow this concept with a blazing degree of intent. By its very nature legacy code needs to be better and no matter what you are doing or where you will need to improve it.
In legacy code it is always a temptation to leave behind the small things. Let's take for example a small function that has two 'return' exit points. While you can agree that such a small function may not cause too many problems and changing the function violates YANGI you can fall into a trap. Some else comes to that function and follows it's structure to add yet more exit points. Soon the function carries more technical debt weight then you came across it. With the boy scott rule you leave nothing behind, if you see it might cause problems not only for you, now, but also for the team in the future you make it better.
I'm going to write more about technical debt at a later date but it is a subject also worth covering at a legacy level.
Legacy code has a high level of technical debt by it's very nature, in following the series so far the debt is being managed and repaid. The danger you face is adding to the technical debt and never overcoming the debt mountain.
Consider very carefully the single responsibility principle, legacy code tends not to follow this principle and in the refactoring work your first aim is to strictly follow this principle. Failure to do so can result in code mixing concerns and in turns causes technical debt.
If you start to work with the code more, adding new code and failing to follow this principle can cause technical debt.
So why technical debt? Consider that when you leave the code behind and some else picks up the code if the code still has problems those problems need to be overcome, that takes time, resource, money (all debt to you, your project and your company). I do hear sometimes debt can be occured if a programmer is unable to work with the principle, such issues should be measured and balanced against the debt (what is the real cost).