2. More Pub Time

Before we begin the book proper, there is a key principle that we should look at first. At the time of writing, it is highly unlikely that you have ever heard of this principle before now. I would like to say that it comes to us as the result of some super secret research conducted over many years by a shady, off-the-books, clandestine government agency and that it somehow fell into my hands.

I would very much like to say that, in the interest of the greater good, I am now leaking the details of that principle into the public domain so that it might be read, understood and digested for the benefit of all mankind.

I can do no such things though.

Sadly, the reality of the situation is much more mundane.

I made it up, specifically to act as the unifying theme for the content that appears within these pages.

Introducing the “More Pub Time” principle

If I were to express the principle in a manner that is both short and to the point, it might be expressed thus:

I’m not a big fan of jingoisms though, so let us proceed to break that down into something that makes a great deal more sense.

What is the right kind of knowledge?

The principle as stated up there leaves itself wide open to being accused of baldly stating the obviously. If a developer has all of the right kind of knowledge in their head, then it should naturally follow that the quality of their application code will be of a high standard.

But what is the right kind of knowledge?

To answer that question, we need to qualify a few things first, including something of a definition for evaluating code quality itself. Fortunately for us, we can stand upon the shoulders of giants and examine the work that has already been done in this arena.

  • The functional quality reflects how well a particular application serves its intended purpose.
  • The structural quality reflects on the non-functional requirements and how well the application code supports the delivery of the application’s functional requirements.

Fitness for purpose, as it is commonly known, isn’t something that we will be considering here; building an online word processor that can compete with a desktop version will have very different functional requirements to trying to build out a social network specifically for Alaskan tropical fish enthusiasts.

The functional quality of any given software project will be judged by criteria that are very specific to that project. In other words, does it do what it is supposed to.

However, we certainly can examine the non-functional requirements of any given software project in order to judge the quality of the software and its constituent code. Typically, this is done by assessing four key factors.

Reliability

Can we trust our application code to do the right thing? It might sound a bit daft on the face of it but this is something that we absolutely must be able to do. Our users will rely on our application’s code to deliver the functionality that they need, else they will stop being our users and go look elsewhere.

The companies that we work for will rely on our application’s code to be able to deliver the necessary functionality either to increase sales, reduce costs or any other way that might improve the bottom line. Failure to provide for this kind of reliance might result in the company going bust or us getting fired.

The keyword here is failure. The reliability of an application, or an individual portion of code inside an application, isn’t just down to how well the code responds when given the right data in a low stress environment - coding just for the happy path does not provide us with the reliability that we crave!

No, the reliability of a piece of code or an application as a whole comes down to how well that code responds to errors, failures and defects. If a caching layer is down due to hardware or networking issues, will our application choke and die? Or will it handle the situation gracefully?

If a user provides us with garbage in an HTML form, either innocently or maliciously, does our code validate and sanitise appropriately, chucking up the right kind of error message whilst rejecting the content of that form?

Modelling and assessing for reliability comes in many different flavours, far too many to discuss here, but they all have a common theme: Does the application do the right thing when conditions are favourable and does it still do something acceptable when conditions are unfavourable?

If the application chokes when it is fed with garbage data, if our web site falls over once the database’s connection pool becomes saturated, then our quality in terms of reliability could be said to be very low. As we could be said to be out of a job.

Maintainability

I’ve ranked these four quality considerations in order of importance, which is why maintainability comes in second. Reliability is right there at the top of the list since we need our code to do what it is supposed to, and respond appropriately when it can’t.

However, maintainability is a most definite second on the list when considered in order of importance and for very good reason. Whilst the other three members of this list express their focus on a given snapshot of the codebase, frozen in time at any given point, maintainability focusses on both the frozen snapshot and a time-ranged consideration.

This is important for a number of reasons. In an online world, and especially in an online world of applications written for the web using languages such as PHP, the applications themselves very rarely reach a state of completion.

Unlike their counterparts in the desktop world, there isn’t a point in an online applications lifetime where the business declares that the product is done and it’s time to get the DVDs pressed and the product on shop shelves.

This is especially true for development teams that use agile methodologies and lean processes, tagging and releasing incremental changes over time in order to improve the product offering for the targeted end user.

This is where the time-ranged consideration comes in. Code that is maintainable is code that is resilient to the inevitable changes that come along. It is the opposite of code that is brittle and/or fragile. It is code that is sufficiently malleable that it will bend and flex appropriately to accomodate the seemingly endless flood of change requests emanating from the business team without hiccup, downtime or the loss of that most valuable commodity: Pub time.

Security

Security is perhaps the most commonly misunderstood aspect of software quality. Naturally as developers we are keen to protect our application’s data from the more malicious elements of the outside world but security has a much broader sphere of influence beyond the common, though no less critical, act of guarding against known attack vectors.

As far as security is concerned, it becomes necessary to consider the topic in much broader terms. One thing that is common to all applications is that they collect, manipulate and store data. It doesn’t matter whether it’s a game, a social network, a corporate intranet or a blogging site, it’s the data that is king in every case.

As far as the security aspect of software quality is concerned then, we must widen the definition beyond preventing hack attacks to one that recognises the preservation of data integrity is paramount.

If the data within our application is “mostly ok” then we’re in trouble since that implies that some of it is bad. We need all of the data in our application to be good data at all times, we need it be where it is supposed to be and not end up in places where it’s not supposed to be.

As a result, assessing the security aspect of software quality entails a lot more than making sure we are protecting ourselves against SQL injection attacks, or hashing user passwords properly. It entails making sure we have the right kind of validation in place and that we’ve put that validation code in the right location. It entails making sure that a multi-stage data manipulation process can be rolled back to its original state should one of those stages fail. It entails a lot of things but the final outcome needs to be this: All of the right data in all of the right places and none of it anywhere else.

Making sure that we’re ready for the user that has ;DROP TABLE users;@hotmail.com as an email address is one thing, but if a member of our team creates an algorithm that accidentally sets every user’s first name to the four character string “John” then we’re already sailing down crap creek anyway and the paddle is nowhere to be seen.

Efficiency

I’ve known developers in the past who have placed an inordinately high degree of importance on creating highly efficient, fast running, low memory usage code. Ones that have declared code can only be beautiful when it’s fast.

Thankfully, most of us already know better.

In the days, months and years before the explosion of cloud computing and virtualisation, the performance of an application could often be improved by an activity known as “throwing more tin at it”. Adding another server to the rack or installing fast hard disks or more RAM was commonly cheaper than paying a developer’s salary for the time required to optimise inefficient code.

Nowadays, we can still “throw more tin at it” but in a virtual sense by spinning up another instance.

Nevertheless, creating code that is performant and efficient is still very important if we hope to preserve our all-important pub time. Code that is already reliable, secure and maintainable can always be optimised for speed and efficiency.

But code that is written for speed first can rarely be optimised for reliability, security and maintainability after the fact.

That’s not to say that speed and efficiency aren’t important of course. An online application that takes thirty-seven minutes to turn a request into a response had better be delivering absolutely critical information at the end of the cycle if it has even the slightest hope of retaining users.

The reality for the vast majority of online applications is that the request-response cycle needs to complete in a matter of seconds, not minutes. Fortunately for us in the online world, there are a number of techniques that we can employ in order to improve the perceived performance of an application and therefore improve the user experience.

Rather than despatching that account activation email as part of the sign-up procedure, we can queue it for an independent process such as a cron or a daemon to take care of.

Rather than parsing and processing an uploaded CSV as part of the request-response cycle, we can move the file to a watched directory and allow the status of the file’s processing to be reported back to the front end by a series of subsequent, asynchronous calls.

Of course, we can optimise the actual performance and efficiency of our application code and not just the perceived performance and efficiency. The developer that performs a SELECT * FROM users and then loops through the entire recordset in memory just to find the row for the user that has just logged in probably needs his or her butt kicked first and foremost before being taught how to write a WHERE clause. Returning a single row in this situation is clearly much more efficient than pulling out the entire table.

Despite being at the bottom of this list, efficiency is still a very important factor in a list of four factors for assessing the quality of an application and its code.

Which brings us closer to considering what the right kind of knowledge might be. Before we do that though, we should take a moment to consider the wrong kind of knowledge.

Hello World!

The learning process is well documented. Not just in programming circles but in any kind of trade or craft, a practitioner will go through a number of distinctive phases. At the start comes the novice, picking up the fundamentals and learning the first principles. It might be horribly presumptuous of me to say this but I’d be prepared to wager that a great many of us began this journey by writing “Hello World” on the screen, all thanks to Brian Kernighan way back in 1973.

Advancing beyond the novice stage is the journeyman, building upon the fundamentals by acquiring additional knowledge and combining it with experience in order to hone their skills and further their personal development before readying themselves for the final stage, that of the master craftsman.

Traditionally, the title of master craftsman would be bestowed upon a practitioner by the guild that oversees their particular trade or craft. When ready, the journeyman would prepare and submit a piece of work as part of the application process and it would be the members of the guild who would judge said piece of work and establish whether they deem it to be worthy or not.

In the world of online application creation we aren’t so fortunate to have such a structured approach to personal development; one cannot readily apprentice oneself to an established master craftsman. As such, our journeyman stage is less a joy-filled skip through a sun-drenched meadow and much more a stagger through a perilous swamp filled with traps and pitfalls.

It’s also huge, thanks to the Internet. The journeyman developer is literally inundated with opportunities to advance their knowledge and abilities thanks to the plethora of materials available to him or her. There are books aplenty, there are courses to follow both online and in more traditional bricks-and-mortar learning establishments, there are articles and blog posts that are way to numerous to count.

Which is precisely where the danger lies; the largely unrestrained and unregulated publication of tutorials and training videos presents a very real danger to the journeyman coder. With such an unfathomably large volume of information available, how does the journeyman coder ever hope to be able to sift the good quality information from the bad, especially when the bad keeps coming at an ever-increasing rate?

As a case in point, as recently as December 2015 I encountered two exceedingly poor quality tutorials linked to in developer forums that I frequent. The first showed how to “easily populate variables using the extract() function”, which is a particularly dangerous “trick” to learn without making the reader fully aware of the dangers involved.

However, even that pales into insignificance when compared to the second tutorial, which illustrated how to use AJAX to send search terms from an html form to a PHP backend that would return the search results back to the front end after querying the database. On the face of it, this seems an entirely reasonable thing to post a tutorial about and as a topic, it has certainly been covered any number of times before.

However, in this particular tutorial, the example code illustrated the creation of a SQL query by iterating over the $_POST superglobal and using the values directly and without any form of validation or sanitisation.

For any time-served developer this should be a horrifying state of affairs; that a tutorial posted in 2015 pays no heed to preventing SQL injection attacks and thus proving the proverb “A little knowledge is a dangerous thing”.

Yet it is easy to forget that new coders take their very first steps onto a coding career path every single day. Any such hapless coder copying and pasting this tutorial code into their own endeavours would become vulnerable to those same SQL injection attacks, at least until such time that they acquire the right kind of knowledge that would let them guard against these attacks.

Which brings us nicely back around to considering just what does constitute the right knowledge. Regrettably, at the time of writing there isn’t one definitive answer to that question. It is also rather dubious that there ever could be.

One of the very great joys that a career in software development brings along with it is the fact that the learning process never ends. No matter how advanced a developer becomes in their mastery of the topic, there is always more to learn. On the one hand, this is because the topic itself is so vast. On the other, it is because the technology progresses relentlessly.

Complete mastery of application software development is entirely unobtainable for these two distinct reasons. At any given moment, there is already too much to fit into a single human brain. And today’s latest technique has every chance of being superseded tomorrow.

Despite this, it is certainly my strongly held belief that there is certainly a catalogue of knowledge that every Senior Developer and above needs to have tucked under their belt. Such a catalogue of knowledge can cover a variety of topics, from very specific morsels such as always ensuring that you escape, validate and sanitise your inputs appropriately to much broader concepts such as the key software development principles, rules, laws and even design patterns.

But why?

The reason itself can quite simply be stated as this; to build better software. More specifically, to build better software expressly in terms of its structural quality so that it is reliable, maintainable, secure and efficient.

Fantastic! So now that we’ve nailed down the definitions of software quality and the right knowledge needed to achieve software quality…

What the heck is Pub Time?

If we are to preserve our invaluable pub time by pre-emptively learning the right stuff in order to achieve high quality software, we need to know what the chuffing heck is pub time?

This is the more jocular aspect of The More Pub Time Principle, which is precisely why it’ll never be accepted by academicians as a valid software principle but in brief it goes like this:

For me, that quite often entails a trip to pub with my friends to have a catch-up over a drink but it isn’t, by definition, limited to going to the pub. Pub time can entail taking your beloved out for a romantic meal. Or it can mean getting home in time to read bedtime stories to the little ones. Or going to watch a play. Or hitting the gym for a workout. Or firing up your games console in order to blow the heads off of alien invaders.

In fact, engaging in any activity that improves the quality of your life and its enjoyment can be considered as “pub time”, in comparison to late nights wasted hunting down and fixing perfectly avoidable software defects.

Conclusion

The journeyman stage of a software developer’s career is somewhat ill-defined, and this is certainly all the more true for the developer working in the online world.

Much of the web is built upon open source languages such as PHP, Ruby and Python to name but three. Each of these languages have a dedicated following and are supported by fantastic communities and as such, there is a tremendous wealth of learning resources available both online and off.

One thing that the Internet will never be able to achieve though is the elimination of the journeyman stage. It simply is not possible for a learner, of any craft or topic, to jump straight from novice to master without having spent time in the journeyman phase. This isn’t a limitation of technology that might be addressed in the future, it’s a limitation of the human mind. Knowledge acquisition is done through the process of learning, leaving us at the mercy of our current biological limitations.

What we absolutely can do though is shorten the path that the journeyman takes. When faced with the boggy swamp that separates the land of the novice from the land of the masters, we can pick out a sure, swift and safe path to follow - one that takes us to all the good places to visit and leads us safely past the traps and the pitfalls.

This is entirely what The More Pub Time Principle aims to do in providing its rather nebulous definition:

There are already a number of initiatives currently in play intending to help the journeyman developer find the faster, safer route through the quagmire. One rather excellent resource is the PHP: The Right Way project, which I would highly recommend to PHP developers at every level. Another resource is this book.

The goal of PHP Brilliance as a book is to put all of the right kinds of information in front of you. From architectural concerns such as MVC vs Service Oriented Architecture vs Microservices to a thorough examination of the SOLID principles, from looking at abstraction and inheritance in a new light to considering the frankenstein method of utilising closures.

The goal of PHP Brilliance as a state of mind is to ensure that you are equipped to lead the team in creating beautiful code that is reliable, maintainable, secure and efficient.

Life is short so please do take this advice to heart: Preserve your all-too-precious pub time, and do enjoy the journey along the way.

Last but by no means least please remember; drink responsibly.