I always attend some technically heavy sessions. Often some of what I hear goes over my head – but whatever I learn from rest of it is worth the time. Neil Ford’s session at this conference was one of these.
I am going to highlight some of the learning in the form of tips – listed below in no particular order
Emergent Design– waiting till the last responsible moment to take design decisions. Often trying to predict leads to over-engineering. Prefer proactive to predictive or reactive. Over time a component starts taking more responsibility – that is when you should start tracking its last responsible moment. Another case or over engineering happens when objects start looking too much like real life objects- Neil calls them anti-objects. Emergent design also needs developers to find abstractions defined by idiomatic patterns – both domain and technical. Developers should realize that up-front design can address knowns and known unknowns. It can’t address unknown unknowns. Waiting till the unknowns become known is the only solution. Emergent design also requires documentation to remain in sync with the code. Neil says the best way is to write code that reads like design document.
Importance of Ruby– Its easy to write Java unit tests in Ruby. Prefer language based build tools like Buildr than XML based build tools like Maven. Generally Ruby is a good language for build and test engineers. Ruby has much simpler monkey patching which works exactly like point-cuts in AOP ; allowing testers a sneak peek at what is going on at entry and exit points of important methods/ code blocks.
Cyclomatic Complexity (CC) and Afferent Coupling(AC)- CC and AC are good metrics to sniff out refactoring opportunities. Once you see these opportunities ; you can harvest them by abstracting out dependencies and exposing APIs for the same. CKJM tool measures and reports CC and AC at class level. Events such as merging code bases or reduction in test coverage introduce CC. CC per line peaks near release time as everyone rushes to ship it .
Importance of TDD – Need to write tests for all code including private methods. TDD helps you zero down your debugging efforts at brick level instead of building level. It has been observed that code written using TDD has Cyclomatic Complexity of 2 vs 10 for code without TDD.
Technical Debt- The longer the time taken to put to use a feature that is ready more the Technical Debt incurred. Developers often try to introduce genericness in their code-which increases software entropy leading to accidental complexity. Sonar is a build and automation product- which has a technical debt calculator. Estimating technical debt helps in clearing it. But the real trick it does it that the team starts negotiating repayment with customer or management. Runaway technical debt and management’s insistence on sticking to a particular technology hinders emergent design.