Let's start by discussing software project failures. There are many statistics out there about software project failure rates, so it's hard to come up with a reliable figure. Whatever that value might be, hopefully, everyone can agree with the following: The better its design, the more likely a project is to succeed. A project with good design may or may not succeed, and a project without good design is practically guaranteed to fail.
That's why one of the main jobs for a software architect (if not the main) is to increase the likelihood of the project succeeding.
This brings us to the subject of risk.
Risk In Software Development
Risk is present in everything we do, including software development. Nothing is guaranteed to succeed. But even so, we have to ask the question: Is your software project unnecessarily risky? Don't get me wrong. There is nothing wrong with high risk — high reward endeavours. If you are doing something unique, ambitious or innovative, and you think the risk is worth it, that's great. But how many times have you seen incredibly complex designs that try to accommodate requirements which bring little added value to users? And how many times have you seen software architects create complex architectures for negligible performance gains? I could go on and on. All those fall into a category that I call High Risk— Low Reward Architecture, and it's something that you'll want to avoid. Software development is already hard as it is. If we are going to make things harder, it better be worth it.
Signs you might have a High Risk — Low Reward Architecture
From its requirements to its technologies and team, every software project is unique. However, most High Risk — Low Reward Architectures share the following three characteristics:
- The architecture is doing something very high risk. In general, this can either be (a) the architecture is doing something weird (sorry, unique) that almost no one else does. For example: trying to implement a custom persistence mechanism instead of using a commercial-grade database. The other possibility is (b) the architecture is using a database, language, framework, etc… that no one in the dev team (including architects) has ever used before.
- In case the item/s from 1. happens not to work out then the System won't be usable and a new, alternative and expensive design/re-write will be required.
- The added value for customers/users that item/s 1. is bringing is minimal.
Reducing Risk
Now that we know what High Risk — Low Reward Architectures look like, let's discuss some ways for reducing the risk of your Software Architecture.
Functional Requirements
It all starts with the requirements. I strongly believe that the best way to solve a problem is by avoiding the problem in the first place. If you are software developer or architect, the chances are you are a problem-solver and love challenges. One needs to be careful with that. Yes, the most complex requirements will be the most interesting ones to solve. However, if that comes at the cost of very high complexity and risk for little value, consider whether it makes sense to try to implement such features. Simpler, good enough solutions might do. Always remember that a whole car is better than half a plane!
Non-functional Requirements
Even if the functional requirements are straightforward, sometimes non-functional requirements might lead software architects to create very complicated and risky designs. One also has to watch out for that. We mustn't let negligible improvements for example in performance or availability lead to overly complex and risk designs.
Design
In terms of design, you'll want all your services/components to have similar degrees of complexity. Think of each service as a bridge and its complexity as the load on the bridge. With the right amount of care, you might be able to increase the amount of load a bridge can take, but if the load becomes too high, the bridge will collapse. The same will happen with very complex services. Once complexity reaches a certain limit, services become very hard to maintain, extend and operate.
Try to avoid having very complex services, which will usually mean that some of that complexity has to be shifted to other services. So instead of having one very complex service and two simple services, it would be better to have three not too complex, not too simple services.
Tooling
When choosing a database, language or framework, take into account whether the dev team (including you) has experience with it. A project with a database that no one in the team has used before is very likely to fail or suffer unexpected delays. I believe that it's less about the actual tool itself and more about what the developers or architects are able to do with it. For example, if the team has years of experience working and optimizing PostgreSQL, then switching to MongoDB only because it might do certain things better than PostgreSQL is probably a mistake. Your best bet will PostgreSQL. It can take years for people to learn how to use a database or framework properly. The more you can leverage past experience in new projects, the less risky the project will be.
Proof of Concept
Ideally, before development starts, it should already be clear that the software project will succeed. You don't want to find out that the design is not good enough long after development has started. If you are doing something new or high risk, consider creating a proof of concept to show that the design is solid. Proof of Concepts have extremely high ROI: they are cheap to do, they help improve the design and remove uncertainty.
Final Thoughts
Software Architects and Managers tend to underestimate risk. The less hands-on a Software Architect is, the more he or she will tend to underestimate risk and complexity. That very often leads to High Risk — Low Reward Architectures.