Sunday 31 January 2016

Complexity Killed the Design



Software exists to solve problems, some of these problems are born from tedium, a need for speed or a requirement for computation.
Something all these problems share is a degree of complexity both in understanding there nature and in formulating a solution.
In 1986 Fred Brooks wrote a paper entitled "No Silver Bullet — Essence and Accidents of Software Engineering". In it he argues that complexity falls into two distinct categories, essential and accidental.
Essential complexity is caused simply by the fact that the problem at hand is complex, accidental complexity is caused by software engineers themselves in trying to devise an answer to the problem.
Complexity in any design activity should be avoided so if were going to produce good software we need to have strategies for reducing both of these potential sources.
Minimum Required Complexity
Practitioners of agile are familiar with the concept of a Minimum Viable Product (MVP), a product that balances return versus risk, getting us to market quickly to start getting feedback from users.
An engineering benefit of having an MVP is that it reduces the scale of the problem were trying to solve, this in turn will reduce the amount of essential complexity inherent in trying to solve it.
A project burdened with too much essential complexity can very quickly become stagnant, struggling to get off the drawing board or floundering trying to produce a trouble free product that works.
A well thought through MVP will also focus the team on solving the right complexity, it may be that a certain feature would be great for users to have but will derail the team from solving the complexity that will actually make the product viable.
Don't Design By Accident
It may well be impossible for us to eliminate the production of accidental complexity. Software engineering is a difficult activity, mistakes will be made, sub-optimal choices will be chosen.
The best element of accidental complexity is that we have it within our power to fix it.  
A phrase I hate to hear developers utter when answering questions about something they've written is "but it works".
The essence of good software engineering is not that something works, even badly written software normally works, its in how it works. This should lead us to rank working alongside, or maybe even underneath, qualities such as efficiency, scalability, testability and maintainability.
Never stop when something works for the first time, instead ask yourself is there a better move, can this be done better. Its crucial at this stage to know that by better we don't mean by adding new functionality, instead we mean can I achieve the same functionality and increase any of the qualities we've just outlined.
Good design signals intent, it is never the result of an accident. You should never be happy with code that works that you or others don't understand, this means your unlikely to be able to test it effectively or maintain it when new functionality is required or God forbid it ever stops working.
As software engineers we are essentially employed to deal with complexity, we need to make sure we do this in a fashion that ensures there is less of it when we've completed an iteration of a product then when we started.
This applies not only to the user but to the engineers that will come after us, we shouldn't be trying to impress them with our grasp of complicated principles and practices applied to situations where they really weren't required.
Instead we want those engineers to look at our code, nod knowingly, and say "I understand whats happening here".   

No comments:

Post a Comment