Originally published at socket-two.com on 10th Feb 2019.
"Le Gastronomer"
Imagine the following scenario.
It's 09:53 on a Monday morning. You're sat at your desk, at work. Sunlight is filtering in through the blinds of the open plan office space, settling on the rustic wooden floorboards. The office dog scratches the side of its head and creates a cloud of particles, which is somehow both majestic and a little bit unpleasant. You are surrounded by a quiet ambiance, a mix of eager enthusiasm for the week ahead and the lamentations for another weekend gone by.
You've touched and organised all of the email that's accumulated in your inbox since you left on Friday, and recall the final discussions that you had with a hip new client of yours. "Le Gastronomer" - a high-tech city bar and restaurant with a novel menu and funky architecture to match, situated in a central location.
They are commissioning your organisation to make them a web app that serves as their very own, branded food blog, an automatic grocery stock management and ordering system, and, of course, a public presence that permits potential patrons to inspect the menu. You recall that the client was also quite keen to be able to have a high level of control over promotional banners, which, you've agreed, they can configure to appear in several areas of the site. The banner behaviour is also to be dependent on many variables, including the time of year, the time of day, ambient temperature, larder stock levels, dish popularity, and the manual input of site administrators.
At 10:00, you have a meeting with the developers, a producer, and a project manager to discuss how you will build the application. The client has agreed to pay a reasonable amount for the software, but they don't have remarkably deep pockets, so their funds will not permit you and your team a leisurely pace. There isn't much room for mistakes. But you've had your coffee, and its a new, unspoilt project and relationship (for now).
The clock ticks over and the meeting starts. You run through the list of requirements with the team. The developers sit - hunched over, listening carefully, with bright eyes, and a kind of still, impassive intensity that reminds you of a pack of dogs waiting for a bowl of food to touch the ground. As soon as you've said your piece, there's a torrent of implementation suggestions, but after a bit of discussion, the key requirement of the site blog has become focal, and the idea of using an off the shelf solution, Wordpress, has taken hold.
"Getting rid of the need to develop an article-management system would save a lot of time."
"This sounds like a good idea, we don't want to reinvent the wheel."
"Wordpress has a rich ecosystem of extensions - there are several banner managers to choose from, which will cover that requirement."
"It's a very popular system - the codebase is robust and well-tested."
"Client's love it - the interface is simple."
These arguments seem fairly compelling, so the speculation gradually settles down into satisfaction as the team collectively exhales, and one of the developers leans over to help an intern download and install the Wordpress source code into his development environment - to demonstrate it to him. Everyone seems quite content.
But then an oblique figure that has been sat squirming in the corner finally pipes-up.
"I'm not sure if this is such a good idea".
Regarding the concept of "off the shelf" software.
Whenever you sit in an application design meeting like the one described above, the most fateful decisions you can make are decisions regarding the inclusion of third-party code. In particular, its important to correctly identify which parts of the software should be delegated (if any) and, when presented with multiple options, which vendor packages you will use.
Its a very reasonable thing to want to reduce development time by draughting in third party software to serve as ready-made puzzle-pieces, especially in a commercial environment where time is tight. Viewed from afar, this logic is sound, and when done judiciously, the practice of scavenging for parts can work out very well. But in reality, teams are often so keen to save time, that they don't realise they are sabotaging the project, and making things harder and more time consuming for themselves, by jamming a square peg in a round hole. This can be disastrous, and can give rise to a colourful cornucopia of maladies, which I will discuss below.
Pandora's third-party package
Arguments against using third-party code in your application.
Customisation
- It may not be customisable When third party code is used in a project, its generally considered good practice to keep it separate from the application code that is written by the project developers. This usually means a combination of storing it in a separate directory, omitting it from version control, and sometimes, allowing it to update itself. Therefore, its generally considered bad practice for a project developer to make changes to third party code. If nothing else, any changes the project developer may impart will be lost if the third party code gets updated. With this in mind, third-party code is considered immutable. It cannot be adjusted or customised - at least, not by means of opening the third party code in a text editor and making modifications directly - which is the method that gives the most control. A well written third-party library will contain mechanisms that allow it to be customised in other ways, such as accepting a configuration object, or allowing base classes to be extended. However, crucially, its common for situations to arise where the modification in behaviour that you need to achieve cannot be implemented gracefully. In such situations, you have two ugly options. 1 - Tell the client that you cannot deliver the feature they've asked for, or 2 - write some horribly hacky code...which, will usually negatively impact the application in some way.
- It takes longer to customise The allusion that the previous point makes to "code that is not directly modifiable" should illustrate how vendor code can sometimes be more time consuming to customise.
- Customising it may have behavioural side-effects The first point should also provide some explanation for this. A hacky customisation can have several negative effects, and one of these is the introduction of bugs. For example, suppose the client decides that the great big "play" icon that appears inside video thumbnails looks obnoxious and they want it removed. The library doesn't have a configuration parameter for hiding the button, and the HTML is immutable, so the developer issues a hacky fix by hiding the button with CSS. The client is happy, as the play button is gone, and they can still play the video by clicking on the general thumbnail area. However, as the play button contained an aria-label attribute, and is now hidden, users accessing the website with screen readers can no longer perceive the video. Here's another example. Consider a situation involving an online shop, where the client wants the "Item added to your cart" message to disappear after 5 seconds, instead of lingering about indefinitely. Again, if there is no inward-reaching configuration option that enables this behaviour, the developer may, for instance, issue a hacky fix where they force the whole page to reload after 5 seconds. The cart message is now gone, but the site visitor may have noticed that their screen went blank for a short period, and their viewport may have scrolled back to the top. This type of thing can be fairly inconsequential by itself, but as these hacky fixes add up, its not long before the overall user experience turns into digital detritus. If the developer had full control, the fixes would be as natural and as fluid as the water over Niagara Falls.
- It may compromise the integrity of the codebase Sometimes, hacky fixes don't cause bugs straight away, but they do create fertile ground for other bugs to breed. Usually, bugs brought about from an established illogical codebase are more sinister, as they have a tendency to go unnoticed. They might silently prevent 1 in 10 customers form completing the checkout process, or perhaps continually expose sensitive information. The mechanism for this phenomena is fairly straight-forward: A hacky fix is an illogical fix. When a developer is working on an illogical codebase, its easy for them to inadvertently write logical code that interacts badly with the previously established illogical code (which, while in isolation, was quite innocuous). This results in new, illogical bugs that may not be beknownst to the company.
Fit for purpose...?
- Its designed for a general purpose Any given off the shelf software that purports to take a large chunk of work off your hands is not designed to be a perfect fit for your project. Almost by definition, it's designed to be a relatively satisfactory fit for many projects. Therefore, in regards to features and customisation, you will necessarily find that the solution is not ideal in one of two ways. 1 - it is not flexible enough to meet your needs (see above). Or, 2 - it contains so many bells and whistles and customisations, that its not optimal. This brings us to the two points below.
- Computational inefficiency Bloated software may be sluggish, and run slowly. This computational inefficiency may manifest as excessive page load durations, unresponsive interface elements, sticky scroll bars, crashes, and increased hosting costs.
- Complexity - developmental inefficiency Creating a bespoke module for a slim, purpose-built application is likely to be far simpler than creating a bespoke module for a complex system that requires a lot of pomp and ceremony. In the case of the complex system, the module will likely need to be authored in absolute terms that describe its functionality and declare its parameters in a much broader (and frequently, redundant) context. For example, creating a "Hello world" module for the Joomla CMS, a developer will need to write about 100 lines of code, separated across 5 files. To create that same module in a slim system however, its not unlikely that this module could be authored as one line within one file.
- It can be slightly less portable Many projects that include third party code use some kind of automated tool to manage the acquisition of, and updating of, vendor code. Nuget, npm, and Composer are examples of package managers such as these. Npm is a specific type of package manager, known as a dependency manager. What this means, is that when you install one piece of third party software, npm will automatically install all the pieces of third party software that the software you specified is dependent upon. It also installs their dependencies, and their dependencies, and so on. This can sometimes result in very deeply nested directory structures, and large collections of files. When the time comes to move your application to a different environment, moving these files can take quite some time. The process can be made faster by omitting the vendor files from the transfer process, and then using the npm command line utility to install the packages once the transfer is complete - but in this case, you now need to ensure that the command line utility is installed on the destination device. This is not a deal-breaker for most developers, but it can be sufficiently annoying to warrant avoiding package-managed dependencies altogether on very small projects that need to be easily transportable.
Ownership
It's worth being alert to the fact that all the negative things that exist within this "ownership" group of negatives (with the exception of the first) are unique to projects that utilise vendor software. All of these hindrances can be completely avoided if vendor software is not used.
- It may be incomprehensible Before electing to use a particular off the shelf solution, ensure that developers can easily learn how to make use of it. Comprehensive documentation should be available. If not, at the very least, the codebase should be logical and readable. This is particularly important if the software is obscure, and generally unknown in the software development world. Using a third-party solution that is poorly documented, uncommonly used, and generally incomprehensible is a reliable way to initiate a project that is doomed from the outset. Its worth bearing in mind that it certainly, in some situations, can be faster to build good software and document it well, than it is to try to borrow software and decipher poor documentation.
- It's not under your control If you can't edit the code, you don't have full control over the code. You may be at the mercy of the third-party developers who authored the solution.
- It's usage is restricted From a legal perspective, software that you create is owned by you, or your company, and as such, the terms that govern its usage are wonderfully straight forward. In opting to use third party software, you may be agreeing to a variety of limitations. For example, the type of application it can be used in, if you are allowed to profit from it, and how many developers can leverage it at the time of authorship. Sometimes, being able to dispel this looming concern is enough to warrant ditching third-party dependencies. Discouragingly, some clauses in software usage terms are quite vague and unclear. The usage terms of the popular React framework gave some would-be converts cause for hesitation, as it implied that the library could not be used to support any software that was in competition with Facebook. In 2002, Douglas Crockford released his "JSMin" software with an accompanying licence stating that it was only to "be used for good, not evil", which, caused some organisations sufficient anxiety to request that the clause be removed. Hilariously, the licence was amended to allow "IBM, its customers, partners, and minions" permission "to use JSLint for evil".
- It can be expensive Third party developers may charge you to use their software. Generally speaking, this can make adoption rates lower, decreasing the size of the community, and the likelihood that people can help you out if it goes wrong. Furthermore, as a commercial asset, commercial code may be obfuscated, or otherwise made unreadable, to protect revenue. This may also make it harder to modify or inspect. And of course, expensive software will put you out of pocket.
- Abandonment Vendors sometimes close up shop and abandon their package. They might decide that the software has been made obsolete by a superior invention, they may no longer have time due to other commitments, or they may simply loose interest. This can be a problem. The only thing worse than being dependent on software that you do not control, is being dependent on software that nobody controls. Sometimes, on the contrary, software release activity is remarkably effervescent, and software developers release version after version of their package with short intervals. This is generally a good thing, as you can bank on the software being up-to-date, and relatively well guarded against emergent bugs and security flaws. However, the darker side of this is that it can occasionally contribute to the incomprehensibility discussed above. Experiencing a bug with vendor software is incredibly frustrating when the only guide you can find to help you fix it is written with a different version of the software in mind. Frequently, I have been dependent on guides and documentation that do not even state which version of the software they are for. Its more common for this to be a problem with community created guides, such as blog posts, but on numerous occasions, I have found this to be the case with documentation too. Again, this frustration fits in strongly with the notion of control - or lack thereof.
Interoperability
As mentioned above, some third party software can be hard to customise, and this can generally be traced back to the third party developers (understandably) not being cognisant of, or amicable to all possible use-cases and adaptations of their solution. For similar reasons, a larger portion of third party software is also hard to integrate with other systems. When working with software that is composed of a large number of third party solutions, a river-crossing problem often starts to develop: The fox and the grain can be in the boat or on the shore at the same time, but not the fox and the chicken. The chicken can be near the grain, but only when the farmer is also present. As more and more third-party elements are introduced into the equation, the more likely you are to find that some of your packages do not work well among themselves. And therefore, the solution that you must come up with to let them coexist becomes increasingly more elaborate, hard to maintain, and ridiculous. This fact alone can cause project development to slow to a grind, and create negative impacts on the delivery schedule that are several orders of magnitude greater than those of an in-house solution.
Was it worth it?
If, when you started reading this article, you were entirely sanguine about the prospect of using third party software to save time, I would hope that by now that any unbridled enthusiasm you had has been calmed. I would hope, however, that I have not killed off this enthusiasm completely.
Having observed many projects degrade as the result of thoughtless code borrowing, and a lesser amount of projects genuinely benefit from judicious borrowing, my intention is not to feed inflexible phobias of prefabricated solutions. My intention is to instill a sense of caution in developers or producers who think that off the shelf solutions are a simple, conservative, risk-free way to develop custom software with greater efficiency. The decisions that are made regarding the usage of third party software are very important, and need to be approached with care. They need to be preceded with a discerning understanding of the contending packages, and a careful examination of how well these intersect with the project requirements, and each other. But most importantly of all, remember - when developing bespoke software, sometimes it really is more efficient to start from scratch!
Revisiting the architecture for "Le Gastronomer"
Having established that the legitimacy of an off the shelf solution is a question of the projects nature, lets revisit the hypothetical "Le Gastronomer" project and discuss the merits and pitfalls of the Wordpress proposition.
Before we begin, I should confess that the "Le Gastronomer" scenario is ever so slightly unrealistic. In a project team of about 4 - 8 people, as we have here, if all of the developers but one have understood the "Le Gastronomer" project requirements, and are advocating a Wordpress implementation, its not a very discerning team. Due to its low learning curve, Wordpress does tend to get overused and abused when constructing websites, but dedicated development teams are not typically to blame for this.
Regardless, let's begin by examining the development team's remarks. Each statement has an element of truth, but each statement is also flawed. None of the statements fully pertain to the real nature of the project requirements, or the scenario at hand in general.
"Getting rid of the need to develop an article-management system would save a lot of time."
It is true that out of the box, Wordpress will give you robust and sensibly feature-rich blog-post-based CMS functionality. Using Wordpress will circumvent the need to write code for an admin backend, user authentication, an article administration user interface, and database create, read, update and delete operations. However, in the grander scheme of things, and in the context of this project, its not true that this will save a lot of time. The development of such features are bread-and-butter for many developers, and can be written from scratch in less than a week. Any time that would be saved by using Wordpress for this website would be lost - probably several times over - to fixing issues arising from trying to bolster a light, fairly encapsulated platform with inventory management system integration, and heavy customisation requirements.
"This sounds like a good idea, we don't want to reinvent the wheel."
This is an unsound analogy. Building an article management system from scratch is not so much reinventing the wheel, as it is choosing to construct a sleek, efficient lightweight chassis over grabbing a suboptimal one from the scrapheap. (No disrespect intended to Wordpress - it does have valid use-cases 1.)
"Wordpress has a rich ecosystem of extensions - there are several banner managers to choose from, which will cover that requirement."
This is the most flawed statement of all. It is true that Wordpress has a rich ecosystem of extensions, and there are undoubtedly some good ones for managing banners. However, the client has very specific requirements regarding the behaviour of the banners. There is also some very advanced functionality that has been described, in which the data that governs the banners must be carried over from a wide variety of subsystems, including weather APIs and a stock level manager. The chances of finding an existing Wordpress banner manager that does all this is nil. Finding one that does some of it, and then hacking it to do all of it, is a terrible idea when compared to the prospect of simply creating it from scratch.
"It's a very popular system - the codebase is robust and well-tested."
This statement alludes to the fact that popular systems tend to be very stable. The logic goes like this. The more people use the system, the greater the collective effort is to keep it watertight, and the more impenetrable, and generally bug-free it is. On the other hand, however, it could be said that the more people use the system, the greater the collective effort is to find exploitable weaknesses, among hacker circles. I am playing devils advocate in acknowledging this though. The countermeasures established in popular software do tend to outweigh the effect of hackers trying to bust open something big.
"Client's love it - the interface is simple."
Many clients do tend to favour Wordpress over other content management systems, as the result of its simple administrators interface. This is a veritable point, but its not particularly relevant if using Wordpress will cause the software architecture to collapse in on itself.
Using third-party software responsibly
This has been a philosophical article, so lets go the whole-hog and close with some analogies. Consider the role of a software developer to be similar to the role of a musician, illustrator, writer or mechanic. All of these roles require the author to carry out a creative process. In a creative process, lots of factors govern success, and as such, one of the best words to describe the effort is "artistry".
A good artisan takes pride in their work. They work carefully and methodically. They do not make rash decisions, or act impulsively. When making architectural decisions, keep these qualities in mind, and you should have some degree of protection from adversity.
Lastly, lets consider the creation of software to be like the creation of a vehicle:
- If you want to create a boat that you can live on, don't take a small life raft and pile on a toilet, aga, four-poster-bed, writing desk, cross trainer, sauna...It will sink.
- If you want to make a robust tank that will survive even in the most hostile environments, don't take the thickest armour plating money can buy, only to stick it all together with spit and honey. It will be fragile.
- If you want to make a vehicle that flies and dispenses fast food, don't just chop a burger van in half and solder the back end of a plane onto it. It will be inelegant, and hard to subsequently modify.
- If you want to create a car that runs smoothly, don't go to the scrap heap and collect a Toyota gearbox, a Volvo engine, a Mitsubishi clutch, a Skoda axle, and a variety of wheels - It will not run smoothly. And
ifwhen it breaks down, it will be confounding. 2
Instead, if you want to make your own vehicle of any kind, consider building it from scratch to exactly meet your requirements. You may find, after some investigation, that it won't take any longer to build it from scratch, than if you were to have had a "head start" by sourcing existing parts.
If, after careful thought, you have a strong conviction that you can save time by using spare parts, then make sure that you learn about what all the parts do, and how they all fit together before you start assembling. Carefully select a variety of compatible parts that will give your vehicle the features that you have in mind. If you can't find a suitable part on the scrapheap, don't angrily grab the wrong part and say "to hell with it". Make that part from scratch - when your engine is purring, you won't regret it. Once you have all your parts, - one of each necessary component - don't rush the job too much - put them together carefully, with pride and with love.
And if the foreman ever tells you that there is no time for love in your work...find somewhere else to work - lest you end up nothing but an ineffectual, disinterested mercenary! Sublimated love is what makes the software strong!
Footnotes
1 Please do not misconstrue my comments about Wordpress and Joomla as criticisms of each piece of software, in and of themselves. Both systems have valid use-cases, and I am personally a fan of Joomla, and have admiration for the Joomla project. Please understand that I am only criticising decisions to use either of these pieces of software when they are not the correct choice for the project at hand.
2 Please do not misconstrue this analogy as an attack on any of these particular vehicle manufacturers. I am only describing how mixing parts of disparate origins can result in a dissatisfactory and irregular whole.
Top comments (0)