5 Fallacies In Software Design and Development
I have spent the last fifteen years working in a large financial institution building software products for business needs. I’ve heard and seen people make mistakes over and over again that lead to poor results in building apps and software.
Here are five common things I’ve overheard in the past and why they risk damaging the quality of the software we produce. I hope you never have to face them.
1. Building software is like building a house
There is a large population of people who still think that building software is like building a house. The tools needed to build a house with are often compared to the tools needed in software building. For example, blueprints vs tech specs, raw materials vs hardware resources or construction workers vs developers.
A house is extremely costly to redesign and rebuilt if we make mistakes. But it’s also quite difficult to visualise what a room/house will actually look like until most of it is finished.
Consider this hypothetical example. Mike has just completed refurbishing his house based on a design by an architect. The first time he looks at his bathroom, he realises he doesn’t like where his sink is and wants it two feet to the left. But his contractors and site engineers say that’s not possible without a massive rebuild because they will have to move the plumbing and they can’t do that without removing parts of the floorboards, which in turn cannot be done because it’s connected to a load-bearing wall.
Ok, I agree that is a bit of an exaggeration, but I’m pretty sure there are plenty of Mikes out there in the world who are simply left with a bathroom that they aren’t satisfied with.
Building software isn’t like building houses anymore.
With modern development practices, there are three main benefits that can help prevent a similar ‘Mike’s Bathroom’ scenario:
- Early feedback on the product either by using test frameworks to mock the behaviour or to release useable prototypes as soon as it’s ready.
- Rebuilding has become cheaper. By having repeatable automated tests, we can safely rebuild parts of the code and still keep bits that works.
- Building software by small components or service oriented architecture allows us to change small parts of the software without greatly affecting the whole software.
In today’s world where things need to adapt quickly to demands or trends, it’s important to build things that are flexible. We need to be able to take in feedback and respond to changing user requirements quickly even at very early stages in the process.
2. We should rebuild this old UI exactly, as a web page
There’s a growing trend (rightfully) in building most User Interfaces (UIs) as responsive web pages. Web pages avoid the need for custom distribution and installation channels or additional software layers to render screens on a computer. Consider an app that needs to be coded, packaged, deployed and then downloaded and installed to run as a window on a desktop, versus opening an internet browser from any device and connecting to a URL link.
Round about a decade ago, building UIs using C#, Java Swing or Visual Basic forms became a common trend. Many of these software are still in daily use but in need of enhancements due to new business needs. It’s not uncommon to replace these old software with a more modern web interface, especially if we’re unwilling to invest in enhancing old software.
The real concern is when UI developers completely replicate the existing software as a like for like web page without thinking at all about redesigning the user experience.
A large number of software developed in the last twenty years were not built with good design processes or adhering to good practices that have emerged in recent years. Frameworks such as User-Centered Design and User Experience Design Process (read #UXDesign articles) have revolutionised and improved how we build interfaces.
Let’s contrast software development styles twenty years ago with recent practices:
- Traditionally, a business requirement is given to an analyst who then translates that to a design spec. That spec is in turn given to a developer who builds and completes the interface before presenting it to the user when it’s completed. User complains that it isn’t very intuitive but the developer says it’s too costly to change (see “Mike’s Bathroom” above) and ends up living with it and using it for the next fifteen years.
- Today, the User-Centered Design framework encourages collaboration and early feedback which allows users to build highly usable, intuitive and great quality user experiences. Contextual Inquiries, Wireframing and Story Boarding are tools that have proven to create fantastic user experiences to produce high levels of satisfaction.
If we took an old interface that was built ten years ago and merely replaced it exactly as a web page, we are missing out on a fantastic opportunity to provide a better quality product for our users.
If there’s a need to rebuild a page, we should start again from a blank piece of paper and go through current design processes.
It doesn’t matter if users think that “the old one works fine so there’s no need to improve it”. They may not realise yet that there are improvement opportunities which can be incorporated in the new software.
3. We can’t change iteratively because we already have existing complex business use on our software
Business is already live on an existing product and users and stakeholders can’t see how iterative release and being agile can help them. I often find software that are only released after long periods of development and testing cycles, which can take months.
While running software in a test environment can provide some early feedback and validation on changes, there are more frequent and realistic feedback that we can get if changes were actually tested as close to how it would actually be used day to day.
In the case where we are unwilling to rebuild software from scratch, there are still many ways of forcing iterative release cycles to get more frequent feedback.
Here are a couple of ideas that have proven to help test and safely release code regularly:
— Build safe parallel production environments.
For those unfamiliar to common deployment practices, the Production environment (or Prod for short) is the environment where software is live for actual business and daily use.
Parallel Prod is a dedicated test environment with new software changes that uses data from Prod — data flow, stored user interactions, replicated database tables, etc. This can be done as a real-time or batched feed of data to test new changes in software.
By comparing outputs from both Prod and Parallel Prod, we can assess whether the software changes have had any negative or expected results.
— Beta testing with a subset of users.
Beta testing tends to work better with User Interfaces or with software that have a lot of users.
Facebook very famously went through multiple iterations of interface re-designs in the early years. The way they tested this was to simply migrate a proportion of their users to a new interface while keeping the rest on the old. Doing so, they could still get feedback from the new changes and not cause adverse effect to majority of their users.
4. It’s ok to prototype the app first and then worry about how to test it later
We should always write test cases as we code because: it immediately validates the behaviour of our code and it encourages regular software releases
Test Driven Development (TDD) is the practice of iteratively writing test cases first or while coding business requirements. This allows the developer to fully understand what is really required and validate the code with actual scenario tests as they go along.
I’ve recently seen a trend, which I’m now referring to as Development Driven Testing (DDT), where a developer would write test cases only to test code that’s already been written. This may result in missing the actual intention of the user requirement.
For example, if there was a piece of code that had an error or bug which a developer then writes test cases for, it might end up incorporating the bug without realising.
In contrast if the test case was built as specified by the user story before, we’re more likely to realise as we’re writing the code that there is a bug in it because the test case will fail.
Another reason why having a good test harness for software from the start is that it facilitates releasing code regularly without the risk of major issues.
The most common argument against this is that because it’s a prototype, we’ll only be using the software in a test environment. Prototyping is great but should not be limited to only a test environment. Getting people to use the software in a live, production environment will give the best feedback and validation of what’s been build.
Having a good test harness is the key to safely releasing code without introducing any undesired effects.
5. We’re going to have to build the cheapest solution
Time-to-market pressures, client sensitivity and budgetary reasons are indeed important things to consider in the overall success of the project.
While developing software, we often hit technical roadblocks and challenges we need to overcome. More often than not, we end up choosing the quickest (or hackiest) possible solution in order to preserve project deadlines, even if this means jeopardising its design or technical strategy.
I’ll admit that I often catch myself using this phrase, but it isn’t always a bad thing.
The real concern is if we only ever take the cheapest available option without securing commitment or the budget to enhance the software after it has been released for public use.
If software is built right, testable and with means of iteratively releasing upgrades, then building the cheapest design to meet target deadlines with the commitment to upgrade them later makes perfect sense.
However, every software that has been released requires time to evolve and improve. We would then need to record and document any additional technical requirements that was incurred due to taking quick fixes.
These requirements must then be addressed in the next project or be resolved as part of continuous software release cycles. Otherwise, we’ll end up accumulating technical faults that will require a massive overhaul to resolve.
Final Thoughts and Honourable Mentions
As I was writing this article, I realised that there are many more fallacies that could have been on this list. Here are a few honourable mentions:
- Agile Methodologies will not work for large projects or projects with tight deadlines.
- We don’t need to have proper UX Design process. We’ll just build iteratively to get feedback.
- We should never use Waterfall Project Management.
- I used that framework in my last project. We should use it in this one because it’ll suit this project.
- We need to solve our underlying technical strategy first, then we can worry about our UX design.
- The project takes ten months for one developer, so let’s get ten developers and it should be finished in a single month.
Do you agree/disagree with my list? Can you think of more? Drop me a comment below.
If you have enjoyed reading this, do click to follow me on Medium.
In my next article, I will be experimenting with User-Centered Design fundamentals and applying them to other creative projects such as illustrations and music writing.
Great article Ken! Agree with the list. Stakeholder or client management can play a big part in the success of the project and the role of the Project Manager or Business Analyst should not be forgotten in the process.