My learning from Just Enough Software Architecture part 2
Published: 2022-03-26 05:28:05

In my last blog we discussed about risks, describing risks, prioritizing risks etc. You can read it [here](https://dev.to/amitiwary999/my-learning-from-just-enough-software-architecture-i0b). In this blog post, I will add my learning of techniques to handle risks.

Once we know what is the risks then we can apply the technique to **reduce** them.
We can use an already existing solution without doing much research or we can do the analysis, research, try a demo and then implement it.
Risk driven architecture focus on technique that use analysis. It includes performance analysis, security analysis, block diagram.

The technique reduces the risks. We can create documents that can help us to handle the repeatable or similar risks so that we don't have to do the same job again and again. The document can contain if we have a risk, consider this technique to reduce it.

To avoid wasting time and money we should choose the technique that best reduces the risks and can help to handle multiple risks. For example, we need to improve the usability of our user interface and we use the technique that already exists. It helps us to reduce the risks. But it may possible that we ignore some important information that can help us reduce the risks more. There is the possibility that the issue is with the framework that we are using and we should spend some time analyzing and fixing it. Time is limited so we should put effort into the technique that can reduce the risks and is more effective.

We try to reduce the risks instead of completely eliminating them because time is limited. We can’t eliminate all the risks. For example, our product work on the browser that 95% of users use. There is a risk that it will not work for the 5% of users. IT doesn’t mean that we will build a new browser that all of our users will install and then use our product on it. Instead, it can be fixed using communication and suer design. Ask users to use the browser that 95% of users use.

**How to choose the technique**

The basic principles that we can use to decide the technique that reduces the risk are:
Some risks use to be easy that we can test easily for example we can test if it is possible to save 100 characters in a column in the database but some risks need to prove for example our API will always return to the client or not required prove that for all possible combination of input it will return something to the client it can be success or failure. We can decide the technique that can help in finding or proving the risks.

Some techniques are already proven to solve some problems and we should use them for that purpose to make sure it is more effective. For example, if the risk is that we are getting a very big JSON Array in the response and the client can’t handle it then throttling can’t solve the problem here instead we have to use pagination that makes sure we send the limited data at a time.

**How much time to invest**
We know that time wait for no one. We can’t spend too much time on the architecture. We need the balance between.
Effort should be proportion to risk: Risk is driven model to apply technology effectively to reduce the risk i.e not over- or under-applying technique. Architecture efforts should be proportional to the risk of failure. For example, if security is not a risk for us then we should not spend time on security design but if performance is the risk for us then we should work on it until we are that performance is good.

When we apply a risk-driven model, we only design the areas that we assume have risks. For example, if we identified that there are performance risks but no security risks then our design model will focus on solving the performance risks only. This we call incomplete architecture where we only design the part that has the risk

The risk-driven model helps us to identify the risks, prioritize the risks and apply techniques to reduce the risks sufficiently. But this ‘sufficiently reduce the risk’ is subjective and we are the ones that take decisions if the reduction in the risks is enough for us or not. 

**Planned and evolutionary design**
We can use Planned, Evolutionary or minimal planned design of our system. One thing to remember is that whichever design style we chose, one thing in common we must design the software before we write the code.

**Apply agile process**
When we start the project, we can find out the initial risks in that project for example the framework that we are going to use, choice of architecture, choice of database. But there are some risks that come later during the development. We need to handle both types of risks.

As an engineer, we use to have some knowledge about the risks in using an architecture design framework and before starting any project we can do a simple meeting to discuss these risks and how we can reduce the risks.

Once we started the development at the end of each iteration we can evaluate if we have added any new possible risks to the project and what is the nature of risks. Small risks can be handled when they arise during the iteration. But some risks use to be large and they need to schedule just like features. So we have to keep these risks in backlog and we can pick it in the next iteration.

Now there is a conflict between risks and features. The product manager keeps adding the feature in the backlog that the engineering team need to pick and work on. The engineering team keep adding the possible risks in the backlog which is also important to fix. So we have to prioritize the risks and features but the product manager alone can’t decide the priority. The engineering team and product manager both need to discuss and decide the priority of features and risks.

**Refactoring**
When we start building any system we use to have limited knowledge and we do the designs and write code based on that limited knowledge. But once we start the development we get more knowledge about the system and have more opinions on the design.

Once we understand that our code is not good enough and can be improved, we have two choices. The first is to ignore and continue working, which yields technical debt and if we allow the technical debt to accumulate the system will become a big ball of mud. The second is to refactor the code, which keeps the system maintainable.

Refactoring means re-design and the scale of a redesign can vary. Sometimes refactoring include renaming the variable to a meaningful name and sometimes it includes architecture refactoring for example changing a database because it can’t support our requirement.