Wednesday, June 29, 2016

Legacy code cycle

“Remember, code is your house,
and you have to live in it.”
― Michael C. Feathers
"Working Effectively with Legacy Code"

Every project goes through stages. First, there is excitement of design, green-field development, seeing things work. Then there are bug fixes, additional features that may or may not fit the originally designed architecture, little tweaks and changes to accommodate the cases not covered in initial development. And then there is support – making changes based on the usage patterns, keeping up with changing environment, fixing the harder-to-find bugs.

Successful projects go through these stages in a spiral: as time goes on, large sections will get re-written to update architecture, move to a new technology stack, fix the underlying issues of the old code base. And then more bugs will be written, tweaks and updates will be needed and will tarnish the shiny new design, and environment will continue to change.

No matter how many times we’ve been there, for most large successful projects, a large portion of the lifecycle is when the code base is full of slow-moving, bug-prone legacy code that is hard to work on. Eventually, an investment will be made to rewrite or refactor the worst pieces, yet a short while later the development organization finds itself facing the same problems again.  

At the same time, developers are being continuously schooled on writing better code, doing TDD, working with legacy code, but all this knowledge turns out to be very hard to put into daily practice.

Legacy code keeps happening, despite the best intentions.

Thursday, June 16, 2016

Are we ready for code review?

We have been talking about the better ways to do code reviews, and there are plenty. There are great tools to make code sign-off by someone other than the code author a required part of the process. It is important to keep code reviews short and casual. Very little code and only a few people should be involved in each event. Reviews should be done often, as much as a couple of times a day, and everybody on the team should participate regularly. There are ways to limit the conversation to the most important topics – logical flow, proper use of language features, good naming, while leaving formatting, test coverage, and many other issues to the automated code checkers.

The most interesting conversation, as it typically happens, took place after the formal presentation. The biggest problem of code reviews, and all other technical reviews, is that we, the developers, tend to take the critique as a personal assault.  People brought up multiple instances when they tried to communicate code feedback to a colleague, and instead their comments were heard as snarky and demeaning. We discussed learning to be nicer, working on improving Emotional Intelligence and social skills, making sure to provide comments on good things as well as bad.

However, this is just one side of the problem. There are at least two parties involved in delivering feedback: a person who endeavors to give the message, and the person who is to get the information. The person who receives feedback must be open and involved into how feedback is provided. In order to learn from and benefit from feedback, we also need better social skills and EQ, as well as trust in the system and the person who is delivering the feedback. 

Thursday, June 9, 2016

OO is getting old and tired. But is it dead yet?

Here are a few thoughts inspired by an excellent presentation with a provocative title “Object-Orientation is Dead, too” by Dave Thomas aka @pragdave.

OO has been taken to mean classes, inheritance and polymorphism, as implemented in a variety of programming languages. As we typically build code, the proper class design is to commingle state and behavior. Inheritance provides a simple way to vary some but not all aspects of behavior on connected objects. And polymorphism provides a way to package different behaviors into look-alike syntax.

Together, these features make for an incredibly flexible system, with many different ways to design abstractions, express dependencies, and store state in many objects across the codebase. Other words for flexible are ‘complex’ and ‘complicated’. The notion that having all this flexibility is good and powerful and smart encourages mixing a variety of abstractions and implementations, and long and wide dependency trees. As systems and corresponding codebases grow over time, accumulating ideas and approaches from many people, they grow more fragile, more tightly-wound. Code also becomes more dependent on the past history, rather than the latest, and therefore best, understanding.   

We know all that because OO had had a great run in the last 25+ years. Java, in particular, has been one of the most popular programming languages since it came out in mid-90s, both by the amount of code written and number of people writing in it. .Net platform is heavily OO and is very popular as well. C++, while not exactly a strictly OO programming tool, is frequently used for OO-style development. Lots of complicated projects have been attempted, and plenty completed, using the OO paradigm. Many people joined the ranks of OO developers, people with varying amounts of education, imagination and cleverness.

In the last quarter century OO paradigm has been applied to many complicated development projects, at times by less-than-stellar developers, and often by diverse groups working independently and inconsistently. OOP came out somewhat scathed, bruised by the many broken abstractions, blemished by millions of lines of legacy code, but by and large OO has delivered on its promise to provide a way to make large and complex systems possible.

So, is OO dead yet? Or, rather, are we ready to move on to something newer and better?

It’s been many decades since OO first showed up, handily won over then-popular procedural programming style, and far eclipsed the popularity of the functional approach. We are now older, wiser, and have more experience. Is OO still the silver bullet it has once been? And what are our options?

Functional languages are powerful, deeply loved by their communities, and offer a paradigm that can rival OO tools in solving complex problems. Yet, the functional approach has not enjoyed nearly as wide an adoption among broader development community. It also did not have such a testing 25+ years, as software projects grew larger, more complex, and continuously involved larger numbers of less skilled people than ever before.

The functional paradigm is worth exploring again, with the experience we did not have back when OOP originally came along and took over the software industry. But the winning paradigm for the next quarter century is far from certain.