I've just finished reading blog by Uncle Bob We must ship now and deal with consequences and I like following a lot:
If you are truly concerned about getting to market early, it is almost always better to do it with fewer features, than with suboptimal design.Whole blog is very good, but you should read Martin Fowler's blog first, to understand the context.
Recent blog of Uncle Bob got me curious about the new metric he mentioned there: Change Risk Analysis and Predictions - in short - CRAP.
It is based on putting together cyclomatic complexity of code and its coverage by unit tests. While the increase of the first represents worsening of code base that leads to the bugs, the increase of second one helps fighting code rot by allowing refactoring and showing bugs when they occur. In theory, of course, your mileage might vary. In my opinion they are good candidates to put into one combined metrics because for example code coverage alone does not say much. Let's say we have 80% coverage. It does not say if last 20% does not need tests because it is too simple to break or just too hard to test. But when complexity raises value of metric and code coverage lowers it, then with correct threshold it can point nicely to places that deserve your attention. So I was interested to see how results of my recent work will stand this test. It took me some time to make crap4j running correctly, because there is some problem with inner classes in test classes and the only way to set up CRAP4J_HOME that worked for me was to modify ANT_OPTS. I was quite delighted by seeing 0% of CRAP in several of small modules I have tried it on. Unfortunately I did not have time to try it with older and bigger modules (not to mention results would be polluted by code of others and I wanted to see my results to give a boost to my ego ;-) ). I might do that later, but I will not publish any results here. Here are some screenshots:In my opinion it is very nice metric, with fantastic name (it was the name that caught my attention). I can imagine it is the name that can create interesting peer pressure if applied in the team. On the other hand, I cannot imagine worse name from manager's point of view. Which manager would like to see report with such a juicy name on his desk showing him how poorly his subordinates work :-) Which manager would not be afraid to show it to his superiors/peers?
Today I have done the first session How to make unit testing better with my colleagues. I am satisfied with my performance, as it was the biggest audience I have ever had. It took me long time till I got enough courage to start - I was thinking about introducing "my tricks" to wider audience of my colleagues since May... (but I've done something in my team sooner).
I was not sure how it will be accepted. Now I know my fears were unfounded. Colleagues appreciated my effort and are happy to continue, they suggested mailing list and wiki to track discussed points. But they might not be aware of fact that they will not be only passive listeners next time :-D If everything goes well, I can imagine that we will get to general topics like design, design principles, clean code and anything else that developers should want to discuss soon. I plan to show TDD soon. I am looking forward to that, but again I am bit afraid that will end up with "20 bored spell checkers". I need to do that interactive as much as possible.My colleague wanted to add comment to recent post, asking how it is possible to achieve good quality of code. Somehow it did not work as he did not see captcha code. Anyway, I owe him an answer (I hope it was not rhetorical question).
What to do?
In my opinion it is not very hard task. To achieve good internal quality of code (easy to modify and extend, no bugs, no environment for breeding new bugs) a few "simple" things must be in use:Continuous learning
Without learning we cannot grow, but because our code base grows, new situations happen all the time and some of them cannot be handled by applying of old tricks (like for example "comments and Javadoc everywhere" that was useful in old days). If you look at your code written 5 years ago and you are satisfied with it, you are probably doing something wrong.Writing readable and expressive code
If code is not readable it takes long time to understand what is going on. If we do not understand code we need to modify problems will occur sooner or later.Continuous and merciless refactoring
Everybody should try to enhance any code they believe can be enhanced. Piece of code could be written nicely, delivering all expected behaviours in the beginning, but it will inevitably rot with time as new features are added, requirements are changed an so on. So it is important to counter attack it with refactoring. Nobody should be blamed if piece of code looks strange and contains code smells after some time. But I believe that all developers should be blamed if they allowed it to happen without trying to fix it. Continuous enhancement of existing code might look like daunting task, but it does not need to be. Any small enhancement every day will do (like renaming local variable or extraction of method). If all team members are doing it continuously they will be rewarded with great code base after some time.Good tests - unit, integration, acceptance
With "good" I do not mean covering everything, but written in way they do not stand in way of future enhancements. They need to be simple, readable and modifiable. Otherwise they will become part of legacy code we wanted to avoid by introducing them. Coverage is important too, but if you are afraid to look at test code because there is no way you could understand it quickly, you have bigger problem, that gets even bigger with time until tests stop serving their purpose and only prevent changes (enhancements) of production code.It works for me
There are more approaches, like pair programming, code reviews, working reasonable hours and so on, but I wanted to mention those that are in grasp of everybody. I said they are simple. What I mean is that there is no magic or something unachievable in them. They only need dedication, persistence and enthusiasm. There might be another virtue needed - courage. Courage to go against main stream of developers (and managers) that are afraid of changes ("If it ain't broken don't fix it" is their mantra). They are just paralysed by their fear. For example I have heard excuses like "But you don't know what class in other module could depend on this so you should not change public API." Well, it seems reasonable, but unfortunately it is good as excuse only. Many potential problems caused by refactoring will be caught by tests for module and all others by integration build. So if it really happened, that some unforeseen dependence failed to compile I will know soon enough. Compare that risk with its alternative - having that terrible code staying as is for next 2-3 years, causing unforeseen problems as other people will hack new features into it in the future. Does refactoring of code still look like bigger risk to you?I found following sentences regarding quality in Art of Agile Development while commuting to work this morning.
The best way I know to reduce the cost of writing software is to improve the internal quality of its code and design. I've never seen high quality on a well-managed project fail to repay its investment. It always reduces the cost of development in the short term as well as in the long term. On a successful XP project, there's an amazing feeling - the feeling of being absolutely safe to change absolutely anything without worry.I wish more people were aware of this and acted accordingly. I have to make sure this happens at least at my present and future jobs.