Sunday 26 March 2017

Code Critique


A constant in the life of a developer is the code review, you have completed your assigned task and now you must ask the rest of your team what they think of your efforts.
There aren't many occupations where on a daily basis you openly invite criticism of your work, there are many aspect of development that are more art than science and so asking others for their opinion of your labours is not always done with relish.
However, the purpose of a code review shouldn't be ritual humiliation or driven by a strong desire to find fault, it has many benefits to an effective software development life cycle.
Automate the Mundane
For a code base to have a level of consistency its important that a common coding style be prevalent, one of the items that a code review should cover is conformance to this style but it shouldn't be the responsibility of the other developers reviewing the code to enforce this.
As well as developers the other reviewers should be automated tools who can be relied upon to ensure the agreed upon code style is being adhered to, it is not optimal to have your experienced and talented developers talking about the placement of brackets or the indentation of a code block.
It is also not practical to expect even the best developer to be able to review a piece of code and identify all or any possible bugs that it may introduce, instead another automated reviewer of your code changes should be your unit test runner.
Catching bugs at the earliest possible opportunity is desirable and catching them before they are merged in is about as early as can be.
A Tool For Education
Code reviews aren't just about gatekeeping they are also an opportunity for education both for the person submitting the code and for the people reviewing it.
They represent a good opportunity to demonstrate new thinking on an old problem, smart thinking for a new feature or a post mortem on the cause of a bug.
They can also be a tool for education on architecture, the history of why code is the way it is or a pre-emptive intervention to prevent a possible new bug.
Agile is all about communication, in its purest form this is face to face but in a contemporary development setting code reviews are as good a place as any.
If this communication channel is being used effectively you should be able to see a change in the topics of conversation as the understanding of the code base and the principles behind it grows within the team.
Observation Over Criticism
It can be easy to fall into a critical mindset when reviewing code, to assume that your role here is to find fault and criticise.
The nature of coding means there is nearly always more than one way to solve a problem, some alternative solutions will be flawed but many will simply come down to a question of style or artistic preference.
Don't approach a code review with an aim of criticism, you should have enough faith in every member of your team as to not assume that a code review is required to stop bad code making it into the code base.
Instead see the code review as an opportunity for observation, could some efficiency be gained in this area? Is there the potential for a bug here? Haven't we done something similar to this before?
The opportunity for a code review to be an educational tool should mean that the aim is not just to review the code currently being presented but all to influence the code a developer will submit in the future.
Developers are human like everyone else they will react better to honey than vinegar, don't create an atmosphere where code reviews are a tool for them to beaten with but an opportunity to learn, an opportunity to influence and an opportunity to shape future code reviews.

Sunday 19 March 2017

We Are What We Code


In 1967 Melvin Conway introduced an idea that would eventually become known as Conway's Law.
"organisations which design systems ... are constrained to produce designs which are copies of the communication structures of these organisations"
At the heart of this statement is the realisation that producing software is a collaborative exercise between many areas of an organisation, and as such the effectiveness of that collaboration will be evident in the software that is produced.
To fix your software you need to fix your organisation.
Trash Talk
In order to not produce monolithic software any reasonably complex system is usually broken down into any number of sub-systems.
Once this happens then the nature and structure of how these systems interface with each other must be defined.
In large systems produced by large organisations it will often be the case that different teams will be reasonable for different sub-systems and as such engineers across those different teams must collaborate to define these sub-system interactions.
Ineffective communication between these teams will lead to badly defined or misunderstood requirements that will become evident once these systems go live in the amount of failure recorded or in the amount of inefficiency in achieving outcomes.
To avoid this limit the barriers placed between engineers, let the techies talk to each other whenever the need arises in whatever informal manner they find most effective.
Idle conversations between individuals will very often prevent untold pain in production and also acknowledge the fluidity of implementation meaning not everything can be figured out in advance in a formal setting.
Hierarchy of Needs
All large organisations have a necessary hierarchy to avoid chaos, functions that need to be performed and work that needs to be accomplished is divided among different teams and individuals.
However very often this structure can be manipulated to best suit the needs or wants of individuals, this in turn shapes internal communication and can lead to software being produced that is structured in such a way as to suit the needs of the implementors and not necessarily the users.
Teams should be structured so that they are aligned to the needs and wants of users, in this way what is best for the users will more naturally align with what makes things easiest for those working on the product.
If certain teams are frequent collaborators but have barriers around their interaction because of the way an organisation is structured they will find ways to work more independently, this may not be in the best interests of the user who wants the sub-systems each team is responsible for to interact seamlessly.
Process over Problem Solving
Processes within a large organisation are necessary for many reasons, to enforce consistency, to ensure goals and outcomes are meet and simply to allow for smooth operation.
But a critical mass can be reached where teams and workloads exist solely to service process for its own sake.
The end goal of any process in relation to the purpose of the organisation, and the users it serves, should always be clear and concise.
We don't deploy software for its own sake, we do it because software is a tool to solve problems, all structures and processes within an organisation should be aligned to that goal.
When this isn't the case a stagnation can exist that prevents software delivery, and hence problem solving.
If your organisation isn't structured around slick software delivery it won't deliver software and it won't solve problems.
Its often easy to be critical when software is deemed to not be fit for purpose, its also very easy to see this as purely a technical issue, why aren't our engineers producing better software?
In fact the question to ask is why isn't our organisation producing better software?
Engineers are only one cog in the machine that brought that software to market, much communication will have taken place to lead to that point and ineffective software can nearly always be seen to have its roots in ineffective communication.

Monday 13 March 2017

Mythical Man Month



In 1975 Fred Brooks wrote what has become a seminal book in software engineering, The Mythical Man Month.
In this book he presents several ideas and observations related to how people develop and engineer software, many of these ideas are still talked about and debated today while we continue to try and learn the lessons that Brook's experiences detail.
I will not attempt to cover all the subjects dealt with in the book but I will present what I feel are some of the reasons why this book is held in such high regard.
Brooks's Law
Central to the book is the presentation of Brooks's Law:
"Adding manpower to a late software project makes it later."
The point here is that attempting to reduce software development planning to the simple mathematics of the amount of work one engineer is capable, of multiplied by the number of engineers, while potentially appealing is ultimately false accounting.
The main reason for this is that it discounts the need for the engineers to act as a team rather than purely as individuals.
Writing software of any significance is a complex business that doesn't lend itself to being sub-divided into well formed tasks that can be worked on in isolation.
Instead engineers will be required to communicate with each other to ensure the many moving parts being developed will be able to be coalesced into a working machine.
For this effective communication to take place a level of knowledge about this end goal and the blueprint for getting there must be inherent in the team, introducing new team members weakens this collective understanding and is a distraction to the team while they bring these new members up to speed.
Irreducible Errors
Brooks makes the observation that in any reasonable complex system there is a tendency towards an irreducible number of errors.
"99 little bugs in the code, 99 little bugs, take one down, patch it around, 127 little bugs in the code."
That is to say that the outcome of fixing one bug maybe to cause bugs in other errors, or that solutions to fix complex bugs in themselves may contain bugs.
This implies that there is a need to manage bugs in a code base rather than to have an unrealistic expectation to eradicate them entirely.
The most important aspect of this being to manage the impact of bugs and to understand those that exist to inform analysis and to formulate plans to fix the most critical without causing equally undesirable consequences to be accidentally implemented.
This also breeds a healthy mindset to expect the code to fail and therefore to build in the automated testing, diagnostics and analytics to enable this failure to be detected and ultimately managed.
Conceptual Integrity
A system should be about more than simply the sum of the various aspects of its implementation, it should in fact implement a concept of functionality that needs to be delivered to end users.
Once this concept has been established it should be guarded and protected, just because a system maybe capable of doing something doesn't mean it should.
Often functionality maybe able to be put to novel or inventive uses but if this violates or does not comfortably sit with the original concept of the system it could potentially degrade users interaction with it by introducing complication or by simply not being discovered by them.
This ultimately leads to a mindset favouring simplicity with relatively complex systems being built over time with users being guided at each stage so they maintain their understanding of what the system is for and how it can be used.
This simplicity and gradual journey towards more complexity will also help the problems of estimation and errors that we've previously discussed as a simpler system is not only easy to use its easier to work on and maintain.
As much as things change in software development they also stay the same, many of the teachings that formed the bedrock of early forays into the art form are as relevant today as they were when they were first written.
Make sure you learn these tried and tested lessons even if the languages and techniques used at the time may not be inline with your current work stream, the fundamental truth of these observations will still hold true.