Monday, 30 January 2017

What's in a Name


Many developers will have heard this quote attributed to Phil Karlton:
"There are only two hard things in Computer Science: cache invalidation and naming things."
Despite the tongue in check nature of this quote most engineers would agree with the sentiment that although the naming of variables, methods and classes would seem trivial it can actually be quite hard and often causes great head scratching.
But what are the root causes for this and why is it so important? Are developers just lacking creativity or is there more than meets the eye with this aspect of programming?
Communication Channel
The reason that deciding on a name can cause a developer anxiety is because he or she realises that this isn't just about what this thing should be called, more importantly its about how to adequately communicate its purpose.
What does this variable represent? What does the method do?
It will often be the case that a difficulty in deciding on a name is being caused by a flaw in the engineering of the code.
Code that breaks the Single Responsibility Principle will be difficult to name because it requires a longer description to communicate all things it is doing.
Code that doesn't have a well defined purpose will be difficult to name without resorting to words like "manager".
If your having problems naming something take a step back and ask yourself what would make this easier to name? The chances our the answer to that question will highlight a problem with the construction of the code and may point to a potential improvement.
Comfortable in Your Domain
Software generally exists within a domain, whether it be a retail domain, a financial domain or a scientific domain.
This domain is likely to have its own language of terms that convey meaning to anyone working within it regardless of whether or not they are a developer.
Its important that when the code and the domain in which it exists interact that the language of the domain is maintained.
If you were to describe what a piece of code is doing to a non-technical colleague they should be able to derive meaning and context whenever these domain terms are mentioned regardless of whether or not they understand the techie speak in between.
If for example "shipment" has a well defined meaning within your domain then it shouldn't be called "order" within the code base.
This will help form a ubiquitous language that enables everyone in the team to have a meaningful conversation about implementation.
The Outcome not the Journey
As with many aspects of development naming should be about outcomes and not implementation.
It is very easy for unnecessary detail about implementation to creep into the naming of a method or a variable.
This can often confuse the reader of your API but more importantly because there is no direct linkage between what you call something and what it does it can become misleading.
A simple example would be a variable called "ordersList" that after refactoring is no longer implemented as a list.
Many things in software engineering that on the surface appear easy can become complicated due to sub-optimal engineering practices.
In these instances its important to listen to the voice inside that tells you that doesn't seem right.
This voice can be triggered by bad names or an inability to think of a name so rather than increase your stress levels by racking your brain for a better name take a step back and re-evaluate the code in front of you.
A name isn't just for identification its also valuable to communicate your intent and to form the basis for the documentation of your code, with that in mind don't worry if it takes a bit of time.

Monday, 23 January 2017

Continuous Business


Continuous delivery is a term often spoken but its consequences are not always appreciated or understood.
Continuous delivery when combined with continuous deployment should create a situation where deployment to production is a complete non-event, it doesn't inspire feelings of either pleasure or dread it is simply a natural consequence of code being produced or modified.
While there is a technical element to building a pipeline to put this into practice, in order to succeed the whole business must be signed up to the process and be willing to let go of fear, control and ownership.
Out In The Open
When a pipeline into production is automated it should be done in such a way as to increase its visibility to all team members and stakeholders.
Rather than a software release being a process shrouded in mystery full of anticipation everyone sees the process from start to finish and more importantly sees the checks and balances being automatically enforced to ensure quality and fitness for purpose.
This openness reduces the feeling that the release is owned by anyone and the decrease in obscurity will increase the feeling that everyone is playing a part in delivery and can see the fruit of their labours.
Its often said that with enough eyes on a problem anything can be solved and the more people that have clear visibility of the route from code repository to production the bigger the likelihood improvements will be suggested and the faster they can be implemented.
Reduction of Risk
Automation can sometimes be a word that scares people, they associate it with a lack of control and sign off that can bring about anarchy.
In actual fact well implemented automation reduces risk, people make mistakes but an automated pipeline can be relied upon to always act in the same way and always apply the same rules and standards.
Automation also carries connotations of speed so even if occasionally a release goes bad automation can ensure we are "not wrong for long" by enabling us to quickly stand up new infrastructure, roll back changes or increase capacity.
That is not to say that badly constructed automation cannot lead to the kind of disorder and chaos that people fear but this is equally as likely with poorly conceived manual processes and the sluggishness of those processes will likely bite just when agility is required to rectify a situation.
Machine Throughput
There will come a point in the growth of any team or any system where the thirst for change cannot be meet without an automated approach.
People generally react badly and perform to a lower standard when they are put under pressure to deliver more in less time, attention to detail recedes and the probability of mistakes shorten.
Automation in the form of machines do not suffer from this problem they do the same job every time and can be relied upon to perform the same checks and balances regardless of deadlines.
In this regard to embrace automation is to embrace quality. It also embraces delivery, it places at centre stage the desire to deliver software and the features it implements into the hands of users as soon as they become available not because of a deadline.
In too many teams a software release is a long drawn out process resulting in a big bang when a large amount of change is delivered all at once with team members running for cover to avoid the fall out.
Instead we should strive to banish the concept of a release, it is not a process that need be paid any mind.
We have created a lean mean delivery machine, code enters at one end and usability exits at the other.
While the writing of software should never be compared to a production line the delivery of that software once its completed should be just as never ending and repeatable as any other factory.

Monday, 16 January 2017

An Affection for C



The first programming language that I worked with in a professional capacity was C.
I'd previously been taught C++ at university but never really fully grasped the methodology or gained an understanding of the nuances of software development.
Moving down a level and learning what many would consider a more basic programming language opened my eyes to what was underlying many of concepts that I'd struggled to get to grips with.
This has lead me to believe that learning a language like C is a valuable exercise for all that want to pursue a career in software engineering if only to understand how this set us on the path that has delivered all of the modern programming languages that we now know and love.
From Small Acorns
When comparing C to many modern languages it can seem that a C programmer has a smaller toolbox at his or her disposable. Quite often some of the more powerful tools available to us in modern languages can seem like magic that we don't always understand but that is making our lives easier.
Learning a language like C where you may only have basic flow control statements like if or else-if, or basic looping such as for and while not only gives you an appreciation for what can be done with these relatively humble constructs but will build your skill in applying them so as to remove your dependency on the crutch that more modern keywords can represent.
While these newer more advanced statements don't exist for no reason and have a time and place it doesn't do any harm to brush up on your skills for applying the tools that used to represent the entirety of what a programmer had available to them.
You'll be surprised how often you can find a more efficient, elegant or understandable solution by going back to basics.
Demystifying the Magic
There are certain aspects of programming that produce an unsettling feeling in many developers, one of those areas is memory management. We are more than happy to leave this minefield up to the garbage collector provided by our shiny modern runtime.
I would never suggest that anyone attempt to second guess the garbage collector or try to play a role in managing memory in a modern language but it doesn't do any harm to gain some appreciation for the challenges involved in writing such a sub-system.
With a low level language such as C where you are closer to the metal you become responsible for allocation and cleaning up of resources and you are introduced to pointers, a term that makes many a developer shudder.
Over coming this fear to understand the mechanics of when memory needs to be allocated, how it is addressed and how you know when to clean it up will undoubtedly enable you to write more efficient and memory aware software.
Understanding Your Roots
The fundamentals of writing good code haven't changed all that much across the years.
The tools available to us may have advanced and the power of the machinery we have at our disposal may have increased but the qualities that identify something as being good or bad have remained surprisingly consistent.
To this end the languages and frameworks we have developed have attempted to place these values at their heart and to make it more natural to follow them without trying.
The scares you acquire when programming in a language that gives you your head and allows you to shoot your foot off will help you gain a new appreciation for why these principles are held in such high esteem and why modern tooling has been driven in the direction it has.
With any subject or discipline its important to understand its history, C represents a seminal moment in software engineering. Its influence can be seen in many languages being described as having C style syntax and applying similar structure and form.
While C is still in wide spread use today the majority of professional developers will likely as not come into contact with it. I would urge anyone who wants to become a student of this subject to consider going back to its roots and seeing how things used to be done.

Monday, 9 January 2017

Metrics to Live By


The use of static analysis tools is now common place in most development teams, they offer a multitude of different numbers and measures to represent a plethora of different aspects of a code base.
Paying attention to all these different statistics and deciding on possible actions would be a full time occupation not just to remedy any potential issues that are being highlighted but also simply to understand what the metric is trying to represent.
So is static analysis simply a waste of time? No, but there are certain measures that its worth paying more attention to.
Code Coverage
I'm not about to preach the virtues of unit testing, I have done that countless times but when assessing the fruits of your testing labour its important to realise that analysing code coverage is about more than just looking at the headline number.
Many tools allow your code base to be broken down in terms of complexity or reference count, its key to marry this with code coverage.
A coverage figure of 80% may sound impressive and more than adequate but if the 20% not being covered represents the most complex and widely used areas of code then this will severely limit the confidence that can be taken from the tests passing.
The headline code coverage figure is still important but try to ensure that this doesn't represent the low hanging fruit of easy to test code leaving the core of your application untested.
Duplication
Its possible for many tools to scan your source code for blocks of identical code and highlight where you have duplication.
Duplication is not only to be avoided in terms of the maintenance over head it brings but when it spreads through a code base it can be indicative of more fundamental problems in the make-up of a system.
It may be that a developer was left with little choice but to duplicate code because trying to make an area of code re-usable was too challenging because of bad abstractions or poor de-coupling.
It may also be that the possibility of re-use simply wasn't obvious because of overly complicated or obscure code.
No matter what the cause duplication in a code base degrades its quality and causes challenges in trying to grow and extend its functionality.
Pay attention to its growth and look to see what structural or architectural problems it may be indicating.
Technical Debt
Most tools have many different measures of technical debt, some straight forward and some complicated to get to grips with.
Mostly they relate to a code base being analysed against a set of rules designed to highlight deviations from agreed principles and practices relating to structure, syntax and coding practices.
These rule sets can be large and are often broken up into different categories of severity in terms of the impact of the technical debt they represent.
No matter what the rule or severity the team must agree on which rules represent how they want to write code and agree that areas of code that break these rules must be fixed.
Too often when analysing the output of these tools teams will skip over violations deeming them not important or not urgent.
Any rule that carries this assessment should be removed, even if they represent small pieces of technical debt they will build up to cause the team to not be able to see the bigger more critical problems and become disillusioned with the benefit of running these types of scans.
Software engineering can be a very creative and intangible, assessing the quality of a code base is not as simple as running the code through a machine and getting a red or green light.
The output of all static analysis tools should be viewed with the benefit of the knowledge you have about the history and make-up of the source, code isn't written by robots.
But they do provide indicators as to where things are going well and where some of your attention should be be directed, use them as a tool to improve things not a weapon to punish each with and make sure you understand what drives the numbers to ensure you maximise their usefulness.

Tuesday, 3 January 2017

Big Bad World


There are an increasing number of businesses whose assets are either entirely or mostly electronic, mostly in the form of data these intangible resources are the means by which many make their money.
A natural consequence of this is that the security of the infrastructure used to hold these valuables becomes of increasing importance, news stories of breaches come thick and fast to the extent that even a lay person is aware of the phenomena.
Given the potential ramifications of such a leak what can be done to ensure all possible security measures are put in place?
Don't Rely On People
Human beings are inherently insecure, we don't have a great capacity for remembering large and complex pieces of information and we can't be relied upon to not inadvertently commit a security related misdemeanor.
When we rely on human based security we are beholden to passwords, in theory a well chosen password gives a good level of security but the practicalities of having to store these passwords inside human beings does a lot to weaken the security provided.
Humans are also unique in their ability to be compromised by non-technical attacks in the form of social engineering, watering holes and phishing attacks, while education to recognise these threats can be affective it should never be considered full-proof.
Technology exists to counteract these threats, whether it be password managers, multi factor authentication or biometrics all are attempting to reduce the reliance on an individual remembering and not exposing the details necessary to access a system.
Obviously a certain amount of trust has to be placed on users of a system but expect that at some point one of those users will make a mistake and ensure this isn't fatal for the security of your assets.
Don't Just Protect The Boundary
Discussions around security will often talk about stopping people getting in, whilst protecting the boundary of a system is an obvious step to take the best security strategies will assume that despite best efforts someone will get through, this leads to the concept of defence in depth.
Any one piece of security or protection can probably be defeated but if this just gives you access to try and compromise the next layer you can increase the time and effort necessary to compromise an entire system to such a point as to be infeasible or not in proportion to the reward.
These layers may consist of the non-technical such as physically securing sensitive areas, the technical such as proper use of encryption and network segregation or administrative such as ensuring sub-systems and users only have the minimum amount of privilege that they need to effectively operate.
Security measures shouldn't just be equivalent to a steel door on a safe they should be a spiders web of measures that impede the progress of would be attackers at every turn.
Complacency Killed Security
Attackers are often very resourceful, creative and intelligent people who are highly skilled in there ability to defeat whats put in front of them.
Many a breached system would have looked comparable with Fort Knox until someone exposed the minor crack of a weakness that blew the whole thing open.
The security of a system should be demonstrable and should be verified by regular penetration testing and probing.
Its also advisable to have an attitude of distrust and pessimism, everyone is out to get you and soon or later they probably will.
Its important to have uncomfortable conversations about how the aftermath of an attack will dealt with, how can consequences be limited and how can security be re-established, the strategy for dealing with a breach is as important as the strategy for preventing one.
The proper application of security is often achieved by the application of many subtle measures to achieve something stronger than the sum of its parts, this is further strengthened via constant re-evaluation, the assumption that attackers are trying to get in and the need for security to demonstrable and not just theoretical.
Good security is also collaborative with everyone understanding the role they need to play and the potential pitfalls they could be exposed to whilst performing their role, together we can attempt to combat a big bad world.