Monday 30 May 2016

More Than Coding



When your starting out in a career in software development its only right that you concentrate on developing your core engineering skills as a coder.
Your primary role is to engineer software and you need to be able to recognise good from bad and have a toolbox of skills you can draw on to build the systems required.
But as you grow into your career certain softer skills start to develop that are important for your growth as an engineer both on a personal level and within the organisation that you are a part of.
These softer skills can easily be overlooked if we assume our only role is to be a techie when actually we need to be more well rounded than that.
Know What You Don't Know
There is a phase in the development of an engineer when their skill is starting to develop that they feel they can conquer any challenge, they are an engineering super hero that will use software to combat all enemies.
Actually no engineer is an expert on everything, no-one has the answer to all questions.
Being a good engineer means having the ability to effectively and efficiently learn how to do something new. Your knowledge and experience makes you able to asses what good and bad looks like, even if you've never seen a technique or approach before you can spot well engineered thought through from the smell of something thats not right.
What is critical is to realise when your knowledge doesn't extend into the area your being asked about, to realise how your going to build that new knowledge and to realise that knowing what you don't know is a skill in itself.
Being a Pragmatist
Another aspect to our developing engineer is to accept no compromise in the application of their engineering skill.
While I would never for one second tell developers that should readily accept incurring technical debt there does also need to be a realisation that software that isn't shipped does nobody any good.
Another skill our developing engineer needs to acquire is a level of pragmatism to know when a compromise needs to be reached between engineering excellence and getting something to users.
The key second aspect to that skill of pragmatism is knowing how to structure the compromise so that it isn't a weight around everyones neck when developing the product further in the future.
Coding something badly is simply bad, knowing when to stop finessing and leaving room for future growth is being an effective engineer.
When Talking to Farmers Talk About Farms
A final awakening for our developer needs to be that they are part of something wider than just developing software.
They have a role to play that is wider than just being a techie they also need to be a communicator whose able to get non-technical people within there organisation to appreciate technical problems and have an appreciation for how the sausage is made.
There is a key difference here between understanding and appreciation, you don't need to teach everyone in the business to code, you instead need to build an appreciation for when a requirement is hard or easy and consequently why a suggestion of a different approach is being made.
You also need to build an understanding of what matters to others in your organisation, understanding there viewpoint while developing the language you need to use to explain how what your doing affects what they want. 
Your role here is to be a technology evangelist building a recognition in those around you of the engineering process whilst not losing sight of the fact that you all need to come together to produce products not just code.
First and foremost you need to become a good engineer capable of producing quality software but always have an eye on the fact that you also need to grow into a well rounded individual who understands all aspects of the business you are in.    

Sunday 22 May 2016

Cogs Not Machines



What does it really mean to construct or devise a software architecture? If we can't answer that question are we just in the code production business or are we following a plan to build something that is greater than the sum of its parts.
We build software to solve a problem but are we also trying to lay the foundations for the solution to the next problem or are we only working in the here and now where we don't worry about tomorrow until it comes. 
With agile practices we've tried to put less emphasis on up-front architecture and bring people down from the ivory tower, so what do we now mean by developing an architecture.
Integrate to Implement
As a software development team we are ultimately tasked with producing something that meets the needs of the user and improves some aspect of their work or play.
However if that is the driver for our architecture then progress from that initial success will require as much effort as the first step we took.
If we construct a monolith of code aimed at solving the problem put in front of us then each subsequent problem will be just as hard to answer.
Implementation should be limited to the cogs that will, via integration, be used to form a problem solving machine. If we achieve this the solution to the next problem may very well require no implementation we instead repeat the integration phase with minor tweaks to the blueprint of the machine.
Re-Use without Re-Compilation
In essence what we are describing is code re-use, but critically this must be achieved without the need for re-compilation.
Some are happy that re-use can be achieved by copy and paste.
What is actually being achieved by this operation is re-use of thought, not re-use of code.
Whoever is copying and pasting the code is simply not having to expend any grey cells on working out a solution to whatever problem they have, the code itself is being duplicated and re-compiled.
If we construct our code into re-useable units, whether we call them libraries, packages or frameworks, we achieve re-use of both thought and code without the need for re-compilation.
We have created a situation where we can build many machines from the same cogs.
Re-Configuration without Re-Compilation
We may construct a piece of code that successfully consumes an API or integrates with a sub-system and this leads us to conclude that we can know integrate with any such system by simply re-configuring the code to a different end-point or URL.
But its important that if this re-configuration is achieved by changing the code then actually what we are producing is slightly modified software not re-using what we already had, this process would have to be repeated multiple times.
Once again re-compilation is not what we want to be doing, all good developers have a healthy laziness that means they'd rather be able to ship exactly what they shipped last time then go to the effort of producing more, slightly modified, software. 
So to go back to our original question, constructing a software architecture is to increase the opportunity for the re-use of effort, thought and code without modification or change.
It should be based on a lethargy that makes us reluctant to want to hit the build button and instead want to point you at the package we've already produced that fits the bill.  

Sunday 15 May 2016

Mobile DevOps



The DevOps movement is a natural extension to the application of agile principles.
If we are good at writing software and utilising IT why would we not complete the circle and use these skills to help us deliver our products.
If you work in mobile development sometimes this can seem like a foreign land, the way we build and deploy software can on first inspection not seem to fit with these ideas but its simple a matter of degrees, we can achieve the same results.
Always Ready to Ship
One principle of DevOps is to have a continuous pipeline to enable the delivery of features into production.
Anyone who has ever submitted an app to the app stores would say this isn't a realistic dream, we cannot submit multiple updates to an app on a daily basis whenever a new piece of code is finished.
But the key here is to realise that the ability to deploy at a moments notice is actually a side-effect of the real benefit we gain from automating our delivery pipeline, and that is certainty about the state of our code.
By consistently and automatically building, testing and analysing our code on every change we always know the health of our application.
If the change makes it through the pipeline we still have an app that is ready to ship but now with added functionality. However, if the change doesn't make it through we still have work to do to deliver that feature and we fall back to the last known good version of the product, which may only be hours old.
We never again will have panic setting in when we're told we need to get a new version out.
Always Ready To Code
So now we can ship whenever we chose what features and improvements do we want in our next release?
Users interaction with software can be unpredictable and not necessarily logically, this is no less true for mobile development.
As agile practitioners we don't try to out think our users, we make a reasonable guess about what we think they want and ship the minimum implementation of that idea, we also expect that guess to be at least partly incorrect.
We detect our mistake by observing our users interacting with what we have built, not by standing over their shoulder but by having our app call home.
Asking one user what they think of what has been produced will not be informative, asking many of them might give a clearer picture but asking every single user all the time gives us a total and thorough view of where we are.
Implementing instrumentation and analytics can provides us with the data to drive our continuous pipeline to deliver a slightly improved experience, when we iterate through many cycles of this feedback we will have moved a long distance from where we were towards satisfying our users.
Always Ready To Work
Its important to realise that DevOps is not actually concerned purely with making our users lives better.
Its actually about realising that within our team we have the people with the skills who can make our users lives better and therefore we should remove all obstacles to allowing that talented team to deliver.
If we make the lives of our developers and testers easier we will maximise their output in the form of new features being delivered to users.
This is as true for mobile development as for any other form of software engineering.
Identify what is causing you pain in the process of trying to deliver your product, then confront it head on.
In many instances technology and software will be the key to reliving you from this pain and fortunately you have a team of people that excel at using and creating technology, you just need to remove what is in their way.  

Sunday 8 May 2016

Minimum Viable Engineering



Implementing a Continuous Delivery (CD) pipeline means automating to a large extend the decision on when to ship.
Not everyone will be brave enough to completely remove a person from the process but if we are to achieve anything like a continuous deployment of functionality that person will be basing the decision on the red or green lights of our automated testing.
So how do we build this framework of automated testing how do we know when our code is good enough to ship.
Minimum Viable Code
Code is the building block on which we build our product, the first tranche of testing needs to ensure that each of these blocks does what it claims to do, we determine this via unit testing.
If we have adequate coverage of our code from unit testing then we know that we can safely compose our system with confidence that when tested in isolation each of our building blocks is fit for purpose.
If we've followed TDD we also know that this isn't by fluke, we have seen the tests fail and now were seeing the tests pass.
By integrating unit testing into our CD pipeline we can be confident that problems at this level will be detected early, the higher the frequency of change in your code base the higher the need for this testing to be automated. 
Minimum Viable System
Just because we have developed trust in our individual building blocks doesn't necessarily mean we can build our jigsaw and just assume everything will be ok.
Part of our engineering skill is in being able to orchestrate these building blocks into a system that achieves a goal, this might be to manage a database, consume an API or process some data.
We now need to move from testing the building blocks in isolation to testing them when they are chained together.
During unit testing the interaction of code with its dependencies takes place in a controlled but simulated fashion, now we need to ensure that end to end processes give the desired result.
We have now moved from building blocks to sub-systems and verified that under the hood our code works.
Minimum Viable Product
The majority of us will be constructing software that people interact with, we provide a user experience where inputs from our users trigger behaviour within our code base resulting in output to be consumed.
Our final level of testing needs to assume the place of our users and ensure that given a certain circumstance, when a certain action is taken, then a certain result is observed.
This behaviour driven testing is the final step that determines whether or not we have something viable to ship.
A green light from those tests needs to be interpreted that we have something delivering the minimum our users expect, a red light should mean everyone stops until the problem is discovered and fixed.
We have now tested our product end to end, if we've done this on a regular automated basis then we have established several points at which we could ship.
Software is complicated, manually testing an entire product is a lengthy error prone process.
The only way to be able to deliver regularly and often is to automate as much as possible, freeing up your human resource to concentrate on more abstract elements such as edge cases and unusual activity.
Software is very good at dealing with the repetitious and mudane we should use that to ensure our code, at all levels, is continually being tested whenever change takes place.