Skip to main content

Why you should Keep It Simple, Stupid!

Insight Published on 28 October 2024

The “KISS Principle” – short for “Keep It Simple, Stupid” - is a well-established design principle across many industries, including software development. In summary, it means that designs and/or systems should be a simple as possible. However, it seems that it can be surprisingly hard to adhere to!

When designing a software solution, the KISS Principle can be applied to the design of the user experience (UX) and user interface (UI), as well as the architecture of the software itself. While there’s plenty of content out there on the many reasons why it is a good idea to follow this principle, this article will focus on real-world examples from one of our ongoing projects.

Simplicity for public-facing solutions

When developing a web-based solution for a wide audience, including members of the public, the UI and UX often needs to meet expectations of users who are familiar with the offerings of the tech giants. They will want Fisher Price’s simplicity of design, an interface with lightning-fast responsiveness, and minimal clicks to complete their tasks. Whilst these are laudable goals when designing a solution, they come at an increased cost in terms of maintenance, development and testing complexity. The larger tech giants may be able to handle these demands, but for SME software houses, they introduce higher risks of malfunction and significant overheads.

When you develop a web-based business application for use by an internal team who will use the solution day-in day-out, your “guide rails” change a bit. In this scenario, data integrity and accuracy are vital and should not be compromised in favour of a “flashier” UI. The technology choices should be “conservative”, given that the solution will (you hope!) be long-lived: it may outlive the lifespan of some recent technology offerings! In addition, the team supporting the application will change over time, so using familiar, industry-standard technologies with minimal third-party components is important to help future maintainability. 

Real world-example: Balancing simplicity and functionality 

Below are some considerations and decisions we made on our latest back-office web application. The constraints and factors which influenced our decisions included:

  • The application would be hosted on the client’s infrastructure;
  • There is a strong likelihood that the client will take over the support of the application once it has been put into production;
  • Once in production, there will be limited budget to perform non-functional upgrades and updates;
  • There will be a limited number of users (<30) who will use the application as their main “day job”;
  • Data integrity and accuracy is essential; and
  • The development team is three developers, two testers, and four business analysts.

Capturing clear requirements

When defining the requirements for a new application, they should be clear and concise. Each requirement should describe a single piece of functionality, with a clear statement of the acceptance criteria that it should meet. Including the entire team – especially developers – in the early stages of capturing requirements ensures they are not only aligned with business needs but also “developable” to implement within the constraints of the application.

By including the developers right from the start of the requirement capture process - through attendance at the “kick-off” meeting with the analyst and subject matter experts within the business –they can provide their valuable input into the analysis discussion and offer an important business perspective, right from the “get go”. We’ve found that this leads to requirements which have been easier to develop and more aligned with standard patterns established across the solution.

Choosing the right core tech stack

The main choice was between a client-side user interface using Angular, or a server-side interface using Razor. Angular is great when you want a “whizzy” dynamic user interface, with lots of interaction points where API calls can be used to adjust the user interface and optimise the simplicity of interaction with the system. However, it undeniably adds an overhead to the development process, with significant skills needed to work on both server and client-side code. The upgrade cadence of client-side frameworks (e.g. Angular) is high, and occasionally major updates will bring breaking changes, which will result in rework (and re-familiarisation).

In contrast, C# .NET hasn’t changed much over the years (with new features being additions, not replacements), and Razor provides a simple way to build native HTML pages. Given that: we didn’t need a user interface to meet the high expectations of the general public; we had a small development team who wanted to prioritise the development of functionality over “style”; we didn’t want to be slaves to constant framework updates; and we didn’t want to leave the client’s support team of the future with an unfathomable codebase – we chose Razor over Angular.

The other argument often rolled out in favour of client-side interfaces is that you get an “API ready” application “for free”: the contention being that the API endpoints you create to support the client-side framework could be repurposed to support B-to-B interactions with other people’s systems. However, it is very unlikely that the requirements of an external application will exactly match an API already exposed, so new endpoints would need to be developed anyway. The authentication is likely to be different too. In the case of this particular application, there were several known requirements for API interactions, which are being developed to meet specific needs, alongside the Razor-based user interface.

Third-party components

When building an application, it is often sensible to make use of packages or components created by third parties. These may provide functionality that would be “silly” to reinvent, although it is important to assess exactly how much effort you will save by adopting a given package, to ensure it is worth using. It is generally a good idea to minimise third-party dependencies.

By using third-party packages, you put yourself at the mercy of the provider’s future plans, especially when creating an application you expect to be used for a long time (well over a decade, in this case). The provider may abandon the package (do no further work on it), which may lead to it becoming vulnerable to future security threats; or they may move to monetise it, meaning that your client is liable to pay licence fees if they want the latest updates. To protect your application from a “tight coupling” to a specific third-party package, it is important to “hide” it behind an interface in your own application code, so that the specific implementation can be easily refactored out and replaced if required in the future.

More UI, less complexity

There is sometimes a temptation to pack more complexity into a smaller number of designed screens than to spread functionality over more screens, each with less complexity. This might simply be in an attempt to reduce the number of screens required, or may at times be perceived to give the user a better experience. However, unnecessary complexity packed into a single screen will usually lead to a far greater risk of bugs - some of which will be found during testing and will therefore extend the test-fix-retest cycle – but worse, some will not be found and may compromise the usability of the system and the integrity of the data, once the system is live.

For example, it is not advisable to perform “operations” on data items from a “list” screen. If you need to edit a record, even if it is as simple as changing a status, it is cleaner and safer to have the user navigate to a separate screen dedicated to provisioning this functionality.

Clear and simple code

It sounds obvious, but writing clear and comprehensible code is sometimes harder than writing “clever but obscure” code, especially when the team includes highly technical developers. The codebase should be readable by junior-level developers, without over-engineering, and with clear explanations in comments where required. This is particularly important if you are going to hand over the application to another team for long-term support.

We have a peer code review process in place (using “pull requests” into the Git code repository). We have mandated a minimum of two developers (other than the author) to review and approve a code branch before it is accepted into the main codebase. This ensures that we get the perspectives of the other developers on the team and checks the comprehensibility of the code.

Develop iteratively

The agile development process is inherently iterative, but if you are not using it, it is still a good idea to develop and deliver functionality in small, incremental steps. Giving the test team, and then the client’s test users, early access to new pieces of functionality, is important in getting early feedback. This allows you to “adjust course” quickly when something is found to be wrong, rather than continue down a blind alley for a long time before realising you are off course.

We have found this particularly useful on our current project, where the full extent of the requirements may not be obvious at the capture stage, because the existing system (which is being replaced) is so old, with few members of the business knowing what it does. In some cases, the business users have only realised that they need some additional functionality once they have seen the functionality they requested during requirement capture. A fast turnaround time is improving the efficiency of the overall application development process.

Conclusion

In summary, the KISS principle is a useful thing to follow on all software development projects, but especially those for a limited back-office audience who value data integrity, efficiency of the development process, and future supportability.

To find out more about our approach to software and UX design, visit our Software Development page!

Topics

  • UX Design
  • Software Development