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.