Sunday, 4 October 2015

Always Be Solving Problems



Aside from the purely technical explanation what exactly is software?
I believe the most productive way to answer this question is that software solves problems. This may seem like a fairly broad explanation, but even a game could be described as solving the problem of boredom.
I believe this way of thinking enables us to better place ourself in the shoes of the user. Unfortunately I think too often we lose sight of why it is we are producing all this software, we assume we need to produce more and more and we assume too much about how users react to all this.
Users Experience Software
Sometimes we can fall into a trap of viewing User Experience (UX) as a distinct element of software when actually it is more pervasive than that.
UX is not the cherry on the cake its the whole recipe.
UI, features and defects all go to make up the experience users have when they interact with software, the moment we concentrate too much on any one element we degrade this experience.
Nowhere is this more evident than when we let ourselves become entangled in a conveyer belt of new features. Its incredibly easy to spoil a slick UX by muddying the waters by layering more and more features together until there is no longer any clear purpose to what we have created.
We shouldn't see software as an arms race, if we concentrate on one problem and provide a great solution users will come and word will spread.
Its no surprise that some of the most popular and successful apps are very simple propositions, they don't need much explaining and they don't readily add new features if it might harm this central use case (as an example think how long Facebook spent deliberating on the best way to introduce a dislike button).  
Be Platform Agnostic
Its a very common occurrence to hear things like
"We need an app that...."
"We should add something to the website that..."
These things are very often uttered very early on in the development of a solution, but they expose a decision being made about user experience based not on the needs of the user but on the desire to be on trend.
The choice of platform, such as mobile app, website or maybe even not a technical solution at all, should be made based on the how the problem is best solved for the user.
We should instead frame these statements as,
"We want the user to be able to ..."
Sometimes this will naturally point towards a platform, sometimes it will be less obvious, but there is nothing more frustrating as a user than being forced to use an inappropriate platform to fulfil a need.
Cutting Edge Isn't For The Faint of Heart
Development of a solution should always start with the problem, if you pick the right problem this guarantees that you will develop something people want.
Many companies fall into the trap of picking a technology first because they want to be seen as cutting edge and then engaging in a desperate hunt for a problem for this technology to solve.
This inevitably leads to unsatisfying solutions that feel forced, users may initially show enthusiasm for hi-tech cool stuff but if your not solving a problem they care about this will be short lived.
A tell tale sign of this is when too much explanation is required for the user to understand the proposition simply to get to grips with the technology, the best solutions to problems are when we just get it and say "why hasn't someone done this before".
As geeks we see software and technology as an end in and of itself, we code just for the sheer enjoyment of it.
As productive engineers we should be looking to answer questions and solve problems, we should understand that people don't interact with code they experience our solutions.
They don't strive for anything more, if you can't keep them on the hook without cracking out the bells and whistles then your not solving the right problem. 

Monday, 28 September 2015

Don't Get Clever With Me


Bjarne Stroustrup the creator of the C++ programming language is quoted as saying,
"C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off."
I think the point he was making is that a good programming language provides a flexible and powerful tool chest for developers to work with but its equally as easy to create a monster then to create a beautiful elegant piece of software.
An important part of working effectively in any language is to be able to chose the right tool for the job, we don't always need the power tools, sometimes a hammer and some nails will do a perfectly good job.
Lets look at some examples of where trying to be too clever might result in problems.
Tying Yourself Up In Threads
There should always be a healthy amount of scepticism whenever anyone says "we need this to be multi-threaded".
Lets be clear threading itself is not actually that complicated, what can very quickly become incredibly confusing is trying to manage access to data and resource once you have multiple threads of execution.
By using multiple threads you open up a whole new potential stream of defects whilst also simultaneously making your code harder to debug.
Using multiple threads is sometimes seen as the only way to increase performance, this is a slightly skewed way of looking at the problem.
Inefficient code is still inefficient when run in multiple threads and few things are less performant than a deadlocked application.
There are obviously occasions when a multi-threaded environment is necessary but this shouldn't be the default position whenever we encounter a performance problem.      
On Reflection That Wasn't Clever
Reflection is a very cool thing, and quite often once a developer gets a taste for it they see it as the answer to all sorts of questions.
But reflection is quite often inefficient and can have a large negative impact of readability.
Bad use of reflection can be seen when we implement marker interfaces (interfaces with no methods) or when we are told to extend a certain class but not to add or implement any methods.
This leads to code without a clear purpose where readers will ask themselves questions like "what does that mean?", "why are we doing that?"
The type of meta-programming that reflection allows can be incredibly useful but it shouldn't be used to the detriment of well structured code with clear purpose.   
Extending The Problem
Many languages provide the capability to add functionality to existing classes, whether it be categories in objective-c or extension methods in C#.
This can sometimes be very useful to avoid constant copy pasting of some utility function but can also encourage bad practice.
Its very easy when using this kind of feature to create a class with an eclectic mix of functionality with the same class being repeatedly modified to do a job it was never intended to do.
This can lead to a class with an inconsistent API lacking cohesion providing poor abstraction.
If your writing a large number of these methods for a class consider whether you can create a new class more suitable to your needs by using composition, this will lead to greater control of not only the API of the class but the also the internal workings.
The point with all three of these examples is not that any of these aspects of programming are evil more that the scale and complexity of a solution should be in proportion to the size of the problem.
We don't need to always open up the whole toolbox at our disposal, within agile their is the concept of the "simplest thing that could possibly work", this not only produces code that is more easily readable and maintainable but ensures time isn't wasted on premature optimisation or gold plating.
Part of the skill of a craftsmen is in being able to achieve wondrous things with everyday tools by applying hard earned skill and experience, this is just as true in software.
Always start off thinking how do we solve this problem using basic constructs, prefer simplicity before reaching for the industrial strength solutions and make sure your not always looking for an excuse to use that new cool feature.    

Monday, 21 September 2015

Progressively Enhancing Your Apps



Progressive Enhancement (PE) is a web design strategy that concentrates on accessibility to ensure that basic functionality is available to all while making the most of available tools to improve the experience for the user whenever possible.
While the practices involved in PE can't directly be mapped to mobile development some of the principles that it employs certainly can be.
Separation of Concerns
A central concept of PE is that content should be separated from presentation, this application of the Single Responsibility Principle (SRP) by separating concerns can be applied to any area of coding that has a UI it presents to its users.
Within our mobile apps their should be code that generates/retrieves data and their should be code that displays that data, their is no reason for these two areas of code to be aware of each other and each should be able to very independently in its implementation.
Code that deals with data shouldn't care what your intending to do with it, code that presents the data shouldn't care where it comes from.
By separating these things out we limit the impact of change and ensure as much re-use as possible.
For example if each piece of UI code is obtaining data directly and we make a change to how that data should be accessed we suddenly have a large repetitive re-factoring job on our hands.
Control Freak
Within a web environment PE will encourage having has much code as possible in an environment we do control, the server, and minimising the amount of code in an environment we don't control, the browser.  
You may think we'll that doesn't apply to mobile we control all of it?
But do we, how much can we change the structure of our code when were working in the UI layer on iOS or Android? Or is it case that we have to fall in line with our Activities and View Controllers.
Even within mobile we should be trying to create an architecture that puts as much code as possible outside of any platform enforced constraints. We have to tow the line in the UI layer but we are king in our service layer, data layer and any other abstraction we chose to have.
When we interact directly with the OS we not only have less freedom in our architecture we are also exposed to more potential change, the next version of Android or iOS might introduce changes that could break us so lets make sure the surface area of our code exposed to this danger is as small as possible.
Don't Assume Anything
The reason PE exists is because with so many browsers and possible configurations out their you cannot assume anything about the functionality or tooling that may be available.
A common problem in mobile development is when we assume we will always have certain resources available to us, most common of these are internet connectivity and location.
So many apps end up just showing empty screens or white space whenever a call cannot be made to a server or the users location isn't known.
I'm not saying your app has to miraculously work even without internet or if the user cannot be located, but it should anticipate that this situation may arise and keep the user informed as to whats going on and do its best to still offer some level of functionality.
Just because we may work primarily in a certain field of development whether that be mobile, web, database or infrastructure there are still things we can learn taking the basic truth of certain principles and applying them to our particular area.
There's always more to learn as a developer and the best way to tackle certain problems is as a group so take advantage of all that collective knowledge and experience by being open minded about what others with a different perspective can teach you.

Sunday, 13 September 2015

Don't Rely On People

An important part of being agile is to be in a near constant state of being ready to ship working software that delivers value to customers.
This means we must have very efficient mechanisms to put the software in peoples hands and just as importantly to verify it is working as intended.
In reality the only way this is achievable is via the effective use of automation, you need talented people to collaborate to construct great software, you need automation to ship great product.
Don't Rely People For Quality
Any production pipeline needs to ensure the quality of the product its producing, first and foremost this comes from employing good people, but even good people can make mistakes and any form of collaboration can result in misunderstanding or differences in approach.
For this reason our pipeline needs certain quality gates to ensure any sub-optimal changes are routed out and fixed and that certain standards are maintained. Traditionally this has been provided manually by things like code reviews and QA testing, if these are your only quality gates you will find it very difficult to be agile and you will ship defects.
Software is complicated, people will make mistakes when their implementing it and people will miss things when they review and test code.
Defects are very often subtle, performing a code review is not like checking someone's spelling or grammar it can be very difficult to truly asses how software will perform purely by reading the source. 
What we need is the cold calculating eye of automation, automated testing and analysis will never miss something because it needs another coffee or because its being distracted by a Product Owner.
Automated quality gates will apply the same rules every time and always take the same amount of time to give code a clean bill of health or point out its failings.
Don't Rely On People For Output
The only way we can be ready to ship at a moments notice is by not needing to be given notice that a build of our code is needed.
Within an agile team their should be no concept of needing to ask someone to put together a build.
Pulling together changes from multiple work streams, coalescing it into one unified body of code and getting it ready to ship is a complicated and potentially time consuming process.
If left up to individuals mistakes will be made and you will find yourself having to ask "is the build ready yet, we need to ship!".
Instead builds and output should just happen, when new code is available it should be incorporated into the product, built, tested and put into peoples hands without anyone lifting a finger.
Once again the machinery of automation will ensure the same unwavering processes are being applied to every single build, all the time.
Let People Be People
So if we shouldn't rely on people to ensure quality or to produce output what should we rely on them for?
Their a certain things we can't automate, we can't automate creativity, we can't automate problem solving and we can't automate enthusiasm to produce value for customers.
We need developers to come up with the engineering that will make our product vision a reality.
We need testers to explore our product, to be the people asking the "What if" questions and be striving to make improvements that will increase the value we're delivering.
In an agile team tasks that are mundane, repetitive and time consuming should be automated, machines are better and faster at these types of tasks and their output will be reliable and unwavering.
For everything else we need to utilise the skills that only people can bring and make sure they can spend the majority of their time utilising these skills. 

Sunday, 6 September 2015

The Fifth Pillar



Traditionally their are four so called pillars to object oriented programming (OOP), these concepts separate OOP from its procedural counterparts and define what the properties of good code should be and some of the tools we have to achieve them.
"Abstraction, Encapsulation, Inheritance and Polymorphism" 
I think their should be a fifth item on this list or maybe even that one item on that list should be replaced, but before we get to that why are these concepts so important?
Abstraction
Abstraction is about the management of complexity and you could argue is the very reason to write code in the first place, to make something complex simpler.
Proper use of abstraction takes a situation that is complex and gradually simplifies by reducing the amount of the system that is in view at any one time.
As an example, I have an application that needs to save some data, do I want every part of my system that needs to do this to be creating SQL statements and interacting with a database?
Instead I create an abstraction of a data store that exposes basic CRUD functionality, now I'm free to put that data anywhere and by any means, no other part of the system cares because they only deal with the abstraction not the implementation.
Interfaces are the currency of this design by contract approach to abstraction, the loose coupling they provide is the single biggest quality a code base can have, its the path down which testability and maintainability are achieved.
Encapsulation
Encapsulation is sometimes confused with abstraction, but while abstraction is concerned with reducing coupling encapsulation is all about cohesion.
Encapsulation is the vale behind which we hide things that you don't need to concern yourself with, we restrict your access because the information we're hiding should have one authoritative source and not be open to change from many different places.
Imagine we were writing code to hold a database of customer records, does it make sense to store all customer addresses in a single array? Or would it be better to have a customer object that has an address property.
The former has low cohesion because the data and the code that operates upon it are separated, the latter moves them together to encapsulate the concept of a customer.
Polymorphism
Polymorphism is the concept that when you look at a class you can see what you want to see, and what you see maybe different to what others see. 
Polymorphism is the natural consequence of the good use of abstraction and encapsulation, once you only care about the interface to an object you start seeing things that might be very different in the same light because they've agreed to do the same thing.
With our data source abstraction we are able to see a T-SQL, MySQL or even a simple array as one and the same thing.
This indifference to detail is what leads to testability and maintainability, my class sees no difference between a real data source and a mock one in a test, you need to start saving data to the cloud, no problem I don't know what your doing with this stuff anyway, just honour the contract. 
Inheritance
Inheritance is the concept that objects can be derived from other objects, most examples revolve around some kind of data model, a Mercedes is a car which is a vehicle etc.  
Inheritance should be considered OOP's nuclear option.
I've seen more code bases in distress because of the bad use of inheritance then any other reason.
Clearly their is a place for inheritance, the majority of application frameworks rely on it, but when you use it in the wrong place it will kill testability and maintainability in a single stoke.
This improper use is usually driven by the so called "is-a" test being confused with "uses-a", for example is a car an engine or does it use an engine? You don't need to inherit from something because you rely on it, it should only ever be because you are and will always be one of those.
The bad use of inheritance is also a very difficult road to reverse out from, once you've built a web of interdependency it has to be torn down not re-arranged.
Composition
The answer, and in my opinion the fifth pillar, is composition.
Composition isn't a grand concept its simple saying you should build big things from using lots of small things, their doesn't need to be a relationship between them just that one is providing functionality that the other can make use of and combine with others to construct something as big as the sum of its parts.
Their is almost nothing that can't be built using composition and the fact that interactions between objects is based solely on functionality means by design you have created testable and maintainable code. 
Preferring composition over inheritance will very very rarely steer you wrong, don't let inheritance become the crutch you rely on because it can very easily become weak and fragile and not hold your weight any more.
Instead use the strength of composition to build systems with strong abstractions, well encapsulated information and use polymorphism to test all the things and adapt at a moments notice.   

Monday, 31 August 2015

Engineering A Developer



I'm willing to bet most of the people reading this who are developers rate themselves fairly highly, its a natural reaction, the output of our labours is out their for all to see, you have to develop a certain self confidence.
But is this self-confidence misplaced, well certainly it would have been when we all started out, development is a trade like any other you have to learn how to do it well.
I'm sure a lot of us began as enthusiastic kids who had the pleasant surprise of finding out that you could get paid to do this.
So how does this skill develop, where do we start from and where do we want to end up.
Hacking It Up
The first piece of code we produced, I'm deliberately not using the word wrote, was probably a bit of a mess with no real structure, we probably would have found it difficult to explain how it did what ever it did but it certainly did something.
At this stage were hackers, we can piece together fragments of code to get something working. We have a basic understanding of what it is programs do but very little appreciation for how they should do it, and what good software looks like.
The subtitles of syntax are lost on us and we wouldn't know a design pattern if it smacked us in the face. Actually most of the time were not actually writing much code ourselves but we're adept at smashing together other peoples.
But at this stage we've been bitten by the bug, our path is set, we're geeks and we want to know all the things.
Programming The Future
So we go away and study, we become fluent in one or more languages, we can reel off principles and patterns and we learn the phrase "You're doing it wrong!"
The skill we develop here is what carries us through the rest of our journey, we have become technically proficient we are developers, programmers, produces of software.
We also develop passion, our code is important to us, we will defend its honour, and god help the guy who tries to besmirch the artistry of what we've written by adding something of inferior quality. 
At this stage we may even be productive, we might think we've arrived but actually we have a flaw, we're all about the code.
Engineering The World
The final piece of development is that we need to gain an appreciation of why our skill is valuable, its at this point that we become engineers.
Engineers realise they are part of something bigger, they are part of a team producing products to put into real peoples hands.
Engineers realise technology is a tool, its part of the journey not the destination. The code is one element of what were doing but we also need analysis, design and testing as part of the process. 
Engineers learn the art of compromise, they develop an agile mindset, a healthy lazy attitude that realises if their working hard we might be building the wrong thing, or at least building it at the wrong time.
I would never suggest that a title is important, it doesn't really matter whether your called a programmer, developer or engineer. What's important is how you got their and what you think your purpose is.
At every stage we've learned a skill that will be utilised again and again, no matter how experienced we become we still occasionally hack something together, we still see a piece of code and think "you should have used a visitor pattern their", and we will always find occasions when we have to resist these urges and work with the rest of the team to produce what is necessary to satisfy the customer.
All I would ask is that you realise what we do is engineering, we may use different bricks and cement but all the knowledge built up by other engineering disciplines applies to our world to.
Embrace this and realise you write code for a reason, we build things, someone else very often will define what that thing needs to be, but we're the ones that make that vision a reality.  
     

Sunday, 23 August 2015

What Is It You Do Here?



Its important when we decide that we need a certain class that this class isn't just a collection of functionality and data but that it has a clear role within our system.
This role should come with clearly defined responsibilities where their is no question that they belong together and no ambiguity over how they should be used.
In order to help us achieve this role assignment and to properly encapsulate responsibilities we can use a set of principles that go by the name of the General Responsibility Assignment Software Principles or GRASP.
GRASP is made up of both patterns and principles that ensure we build a system made of clearly defined blocks interacting in a flexible and clear manner.
Controller
The first of these patterns is controller, the premise of the controller pattern is that a systems UI should be divorced from its logic.
In the controller pattern an applications UI detects user interaction and dispatches these events to a controller object, the controller processes these events and delegates responsibility to executing the required business logic to other classes further down chain.
Controllers are re-usable in any situation where a certain type of user interaction should be linked to a business process.
Creator
Object creation is a fundamental responsibility of any software system.
Creators are designated objects within a system who are responsible for creating the right object for the right task at the right time.
A creator may record instances of the classes it creates as well as supply dependencies along with any required initialisation.
Information Expert
An information expert acts as the single source of truth for either data within a system, functionality or both.
An information expert might provide access to a data source detailing the current state of a system or provide authoritative implementations for things such as encryption.
Indirection
A class providing indirection acts as intermediary between multiple other classes within a system.
When using this pattern classes who must co-operate in order to achieve a goal are isolated from knowledge of each by use of a class coordinating their activities.
The use of indirection increases the possibility of code re-use by weakening the ties between classes.
Protected Variations
Certain aspects of a system are subject to change and this may or may not be directly under the control of those of us that are building and maintaining it.
The use of the protected variations pattern isolates these volatile elements into their own sub-systems and protects dependent code from possible change by placing this functionality behind a well understood interface.
Protected variations should be used to isolate code that interacts with the outside world, in this case the outside world means code not written by us. This might the OS our system runs on top of or a 3rd party library we rely upon to perform a certain task.
Pure Fabrication
A large number of the classes in a system will represent some aspect of the problem domain the system is working in but quite often we are still left with functionality that needs to be implemented.
Classes that we create to fill this void are known as pure fabrication, they do not directly map to any outward facet of our system but are required to achieve the proper break down of roles and responsibilities.
A good example of pure fabrication is the service layer that exists in many system where certain repeatable, potentially re-usable functionality is implemented.
High, Low, Strong and Weak
The goal of the GRASP principles if to achieve high cohesion and low coupling, to have classes who are strong at their core but weak in their interaction.
A class with a well assigned role will exhibit high cohesion, all the inner parts will share a clearly visible common goal, their will be no fault lines where potentially smaller classes could be made.
It should be possible to work with a class with a well assigned role in such a way as to have no knowledge of this well defined internal mechanism, interfacing to such a class should be purely concerned with functionality not implementation.
A good example of this is via the effective use of polymorphism.
Polymorphism should be used to mask an area of our code base that may be subject to a large amount of variation. As a class that is dependent on this are of code I want to be protected from this potential instability and I want to delegate responsibility for navigating through it to someone else.
Polymorphism allows many classes that may be very different internally to masquerade behind the same interface leaving dependent classes in blissful ignorance of the complexity underneath, we achieve high cohesion and low coupling, creating strongly defined classes interacting in a weak manner.
So when your creating a class be sure you know its role and understand the responsibilities that should come with that role.
This isn't just about naming the class properly, its about creating an architecture that fits together just well enough to finish the puzzle but at a moments notice the same building blocks could be re-arranged to follow another pattern to produce a different outcome.          

Sunday, 16 August 2015

Let Me Tell You A Story



When we work in an agile environment we become storytellers, we spend our days spinning yarns.
Rather than once upon a time its As a, I want, So that.
Rather than a beginning, a middle and an end its Given, When, Then.
But how do we tell a good story from a bad story, what makes a best-seller and how do we recognise a trashy novel.
The answer is for us to INVEST a bit of time and effort into our prose and follow a few simple rules.
Independent
One of the major elements that separates agile from more traditional approaches such as waterfall is an acceptance that the outlook is uncertain and we don't plan a long way into the future.
The only way this is possible is if the items on are backlog are independent of each other and can be put into any sequence.
You can't be flexible if the order your stories need to be delivered in is rigid, a backlog should be continually evolving and changing based on the perceived next priority and the next iteration of MVP.
Tightly coupled stories suggest that individually they aren't delivering any value meaning they are disguising the fact that you actually have one big story lurking on your backlog. This in turn indicates maybe you need to re-visit your definition of MVP, is it truly the minimum?
Negotiable
Following on from independence is negotiability, while a story is on the backlog everything should be up for negotiation.
That should include where the story sits on the backlog, what will be delivered and even whether or not the story is required any more.
Stories should capture the outcome not the detail therefore over time they are allowed to change if these outcomes need to change. Not all our good ideas are going to come at once, if someone has a brainwave nothing should get in the way of that value being delivered to the customer.
The point at which we are committed is when that story is in a sprint, at this point everyone needs to be happy that the story is delivering value and is achievable.
Valuable
Stories deliver value, value delivers happy customers.
A story that doesn't deliver value is a sub-task of something larger, this means it is unlikely to be independent or negotiable, we are sleep walking towards waterfall.
When creating stories we should be looking to create vertical slices of functionality with just enough of the layers underneath to deliver value.
Many of the may be tutting at this point, yes this is easier said than done. But we shouldn't lie to ourselves when putting stories on the backlog, sometimes deep down we know we are trying to do too much but we console ourselves that we are agile because we've broken the behemoth into multiple stories.
If something is a large amount of work then it remains a large amount of work no matter how you slice up the pie, completing a story should apply the ratchet effect and leave us better off than when we started not create a race to stabilise the product because we've started something that now we have to finish.
Estimable
We've talked a lot already about our plan being fluid but what information are we using when we re-arrange this plan?
One piece is the value that will be delivered but just as important is how much effort we think is required to deliver it.
If we understand what a story represents why would we not be able to estimate the effort, stories that cannot be estimated are generally too big, not well understood or both. Its also likely in this situation that the value being delivered to the customer is not clearly visible.
The value delivered to the customer needs to be evaluated next to effort required to deliver, we should be biased towards trying to find situations where large amounts of value are delivered by relatively little effort.
As your product evolves these situations will be harder to find but its a sliding scale, small amounts of value delivered by large amounts of effort are not desirable.
Small
A lot of what we're hinting at is that good stories are small stories.
Software development is not always a precise science, as stories get bigger we stretch our ability to accurately estimate the effort and foresee the potential roadblocks.
We are also pushing back the time when we actually deliver the value. The point of trying to fail fast is that the customer is the ultimate arbiter of whether something is valuable, failing slowly to deliver what may or may not turn out to bring value is the worse kind of waterfall.
Testable
So we've created a small independent story that delivers value, we've estimated it and based on all this negotiated its relative importance and committed to putting in a sprint.
How will we know when we've achieved what we set out to do?
Anyone that says when the code has been written doesn't understand how this works, working software isn't an act of faith, working software demonstrates its value by passing tests.
The value a story delivers shouldn't be intangible, it should be able to be made visible to everyone by tests that enable you to see the code doing its thing. If we aren't able to demonstrate the value what exactly is it we think we're delivering to the customer.
Waterfalls are a free flowing body of water, this fluidity isn't present in the methodology that bears its name. Agile is an attempt to break this rigidity and be capable of changing our minds whilst also still delivering timely value to our customers.
Badly written stories will kill this flexibility in a heartbeat, its possible to be doing perfect scrum whilst being totally un-agile.
Scrum is a tool, agile is a state of mind, don't write novels instead write punchy short stories where the customer lives happily ever after while still looking forward to the next instalment.   

Sunday, 9 August 2015

Stupid Is As Stupid Does



I hope all the developers reading this have the word SOLID engraved on their heart, able to reel off those five principles without even thinking about it.
But everything has to have an opposite so what is opposite of SOLID, well that's easy that's just STUPID.
Singleton
Probably the first design pattern most of us learnt was the Singleton pattern and while it occasionally has its uses it is much more frequently an example of an anti-pattern.
A properly applied design pattern should improve code not just now but in the future and should pass this magic on to the other areas of the code that interact with it.
Singletons don't fit this criteria for a few reasons,
  • They encourage the use of global state.
  • Their use causes classes to hide their dependencies.
  • They do not allow for extension.
All of this means although using a Singleton might fix your immediate need it does damage in the long run.
Tight Coupling
For a class to be tightly coupled means it is very susceptible to breaking when anything changes in it dependencies.
You're then left with a choice of resigning yourself to having to fix that class on a regular basis or determining not to change anything in its dependencies. This second choice will inevitable result in some elaborate hacking to come up with ever more complicated solutions to changes in requirements.
This degradation in the quality and structure of the code is the very definition of code rot.
To compound this calamity this ever more complex code will be difficult to test because of the tight coupling, the viscous circle is complete. 
Untestable
Their is almost no acceptable reason for a class to be untestable, very often this is just a slightly different phrasing of saying your code is difficult to use or to work with.
We have to remember that testing our code is not a special activity, it simply involves using what we have written within a test, any issues we find in doing this will surely be just as problematic when we come to using it in an actual application or having to work with it again in the future.
A large majority of untestability is caused by not being able to separate the class in question from its dependencies, either because of tight coupling or because the dependency is simply hidden.
Proper use of interfaces and dependency injection will counter these problems and make your class easy to test and easy to modify in the future.
Premature Optimisation
Developers will very often become involved in intense debates about the optimal way to perform a certain task.
The truth is that in most situations performance really isn't an issue.
This isn't to say that we should give no thought to performance but we should not value it higher than having readable clear code.
The majority of premature optimisations result in code that is difficult to read, understand and work with. This shouldn't be something we want unless the optimisation really is critical, and believe me most of the time it won't be.
Even if you do happen to require a highly optimised system this performance will come from optimising the architecture and thinking about the flow of data around the system, that particular for loop is unlikely to be the key to it all.
As Martin Fowler put it,
“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” 
Indescriptive Naming
In a similar vain, the compiler doesn't care what you call your classes, methods or variables but as a reader of your code I'm hoping you give me a steer as to what's going on by using descriptive unambiguous names.
We sometimes forget that code has to read by others as well as perform the task that is required.
We may think that comments can address this issue but wouldn't it be easier to write code that is self-documenting and doesn't require further explanation?
Their is no mechanism that will keep your comments and your code in sync, a comment that may be accurate now could very easily be completely misleading in the future, whereas the code itself will always describe what the system actually does.
Duplication
Duplicating code to solve a problem has no up side, it results in more code to test, maintain and be a source for bugs.
Problems where duplication is the answer are problems of our own making, we have created a system where parts of the system that should be connected aren't or where areas of the system are required to know or do more than they should.
Copy and paste should be something that makes us feel a bit queasy, surely their must be a better way.
Thankfully answers to all these problems can be found in the warm embrace of the SOLID principles, follow them and you will rarely do anything STUPID.
For every decision you make ask yourself which one of these acronyms would best describe what I've just done. 


Sunday, 2 August 2015

The House That Code Built



Since software development is an engineering discipline we often use language to describe our code that first had a meaning in more physical forms of engineering.
We talk about software architecture, frameworks, platforms and things being SOLID.
But why do we use these analogies and what exactly do we mean by code having an architecture and a structure.
Pointing The Way Forward
The first goal of architecture should be to simplify the problem at hand. Often the problem that needs to be solved is too big to be able to comprehend the way forward.
Good architecture turns this one big problem into a series of smaller problems, meaning when we get to writing code it is very clear how each method, class and package moves us forward.
We will very often find that many of these smaller problems have been faced before, we don't need to re-invent the wheel, we apply the same solution as all the previous occasions.
Good architecture can be seen when each sprint planning session is a smooth affair with little debate about what is trying to be achieved or what on earth we need to write.
Good architecture can be seen when all these individual elements start building on top of each other moving us closer to an overall solution.
Intentionally Emergent
Agile teaches us that architecture should be emergent with limited up front documentation and planning.
The reason we say this is so that we speed up the time it takes to produce working software, this doesn't mean we simply expect good architecture to happen, we provide well engineered solutions to the small problems and build in contingency for the inevitable change in requirements.
By following the principles of loose coupling, strong cohesion and inversion of control we produce a modular, layered design that provides the framework for this emergence to take place.
We not only solve the problem at hand we lay the groundwork for solutions to future problems by allowing our architecture to develop without redesign. We aren't clairvoyant the only aspect of the future we can predict is that change is coming so we better be ready.
Ripping it down and starting again isn't engineering, good architecture allows us to not panic when someone asks us to build an extension to the house. 
This is in contrast to a unplanned architecture that degrades at every turn and causes the solutions to new problems to become ever harder to achieve, emergent doesn't mean lets just see where we end up, it should mean allowing for renovation.  
Proof Not Faith
Good architecture doesn't require you to have faith that it works, it is built to be testable and this testing provides you proof that its working.
The same flexibility that allows an emergent architecture to develop also allows each step along that journey to be undeniably heading in the right direction.
Testability in and of itself is not a property of an architecture its what results from applying SOLID principles, good code is testable code and testable code is good code.
If you ever end up in a position where your architecture is not testable the chances are their are several things its not, such as adaptable or maintainable.
Software engineering shouldn't be a game of Jenga, we shouldn't feel the need to close our eyes when we need to make a change.
Agile is also not an excuse for being sloppy, it isn't about just getting something working its about taking a realistic approach to actually solve the problem not just planning to solve it.
When analysing the problem identify the parts of the solution that are obvious, we need a database or we'll need some kind of API. Put these to one side, we know how to do those, and concentrate on how we can overcome the non-trivial parts of the problem, how can we break this down until we get to a problem we do know how to solve.
Good architecture is a series of really good solutions to a series of really small problems.