Non functional requirements: the pillars of a solid software architecture
Tags: softwaredevelopment, softwarearchitecture, software, development
Published: 2018-11-16 21:25:23

---
title: "Non functional requirements: the pillars of a solid software architecture"
published: true
tags: software development, software architecture, software, development
description: "All you need to know about non functional requirements to be able to choose the most suitable software architecture for your digital projects"
---


<img src="https://thepracticaldev.s3.amazonaws.com/i/rl099ybsi3zorkvpgyo0.jpg" alt="Non Functional Requirements">

&nbsp; &nbsp;
## What are Non Functional Requirements in software architecture

  

Previous to know about **non functional requirements** it is important to know what is a requirement in software engineering.

  

Requirements are the description of a services provided by a system and their operative restrictions.

  

Discover, analyse, document and verify requirements is the process known as **Requirement Engineering**. Requirements can be the base of a **contract** offer or the base contract itself in software projects.

  

There are several types:

- **Functional** requirements

- **Non functional** requirements

- **UI** Requirements

- Domain or **Business** requirements

  

Non functional requirements are directly related with **emergent properties** of a software system and specify or restrict them. Examples of these properties are:

  

- Reliability

- Response time

- Performance

- Availability

They can be much more **critic** than any other requirement. As a result, a flight control system that does not meet reliability requirements will be insecure and therefore unusable.

  

Non functional requirements arise, also known as **Quality Attributes**, from the needs of users, budget restrictions, company politics, interoperability with other software or hardware, external factors like security regulations or privacy legislation.

&nbsp; &nbsp;
## Why you should know about Non Functional Requirements

  

Even if you are not a software architect, and you are a developer, taking care about non functional requirements it's crucial. It allows to deliver great features without compromising the whole system and add **complexity** and **technical debt**.

  

In order to **evaluate** which software architecture is the best for a digital project, it is necessary to know first which are the non functional requirements for the same.

  

Each software architecture style has different **impact** on each Non functional requirement. E.g. [Batch Sequential](https://www.arquitectosoftware.com/docs/batch-sequential/) architecture can have a negative impact in usability while a [MVC architecture](https://www.arquitectosoftware.com/docs/mvc/) has a great perform in this area.

  
&nbsp; &nbsp;
## Main Non Functional Requirements types

In this section are described different types of Non Functional Requirements in the same order shown in [Arquitecto Software](https://www.app.arquitectosoftware.com).

  
&nbsp;
### Supportability

Also known as a **serviceability**, it refers to the ability of a software system to ease **technical support** in some areas:

  

- **Installation** and configuration of the system.

- Provide information that is useful for identify exceptions, debug and isolate the root of problems. Also known as **logging** or **tracing**.

- **Monitor** health metrics of the system.

  

Good supportability results in more efficient maintenance and reduces operational costs.

  
&nbsp;
### Usability

The usability is about how easy it's for a user to use the platform and achieve the expected results with **effectiveness**, **efficiency** and **satisfaction**. These properties are addressed in [ISO/IEC 9126-4](http://usabilitynet.org/trump/documents/Usability_standards.ppt.pdf)

  

Usability includes the ability of being accessible to all people, even those with **disabilities**. This can be accomplished implementing assistive technology in the UI, and providing text for all images and multimedia resources.

  

Good usability results in better **customer satisfaction**, more recommendations, and definitely can boost the organic growth of a company.

  
&nbsp;
### Life Time

  

This requirement is related to **System Development Life Cycle** (SDLC) in which a software system go through a series of **Life-Cycle** phases:

  

- Planning

- Requirement analysis

- Design

- Development

- Integration and testing

- Deployment and maintenance

- Disposal

In order to **discontinue** a software system, there is a process of transition to a new system. Design architectures that take this into account will facilitate **migrations** in the future.

  
  
  
  
&nbsp;
### Cost

Cost can be the **achilles heel** of a software project. There are a lot of elements to consider in the overall cost of a software architecture. The most outstanding examples are:

  

- **Implementation** cost: a more complexity architecture requires more qualified engineers.

- Costs associated to **failure management** and recovery.

- **Data Backup** strategy costs.

- **Resources** needed to run the system: hardware, electricity, etc.

- Costs associated to system **maintenance** and support.

A clear costs example is the one that can be seen in **monolithic vs. microservice costs** at the beginning of a project. A monoholitic app will be less expensive in resources and complexity management than a microservice architecture with orchestration.

  

To highlight the importance of costs in software architectures there is a book with the title: "**RCDA**: Architecting as a risk and cost management discipline"

  
&nbsp;
### Scalability

Scalability refers to the capacity of maintain effective performance during a steep increase in workload without the need to be **redesigned**. An example of this can be a peak of users using the software simultaneously.

  

There are many different methods to scale an application and is largely subject to the architecture and behavior of the application. For **microservices**, [Scale Cube](http://theartofscalability.com/) defines primarily three approaches for scalability:

- Scale the x axis by horizontally cloning the application

- Scaling the y axis by splitting different functionality

- Scaling the z axis by partitioning or sharding the data

  

A more general approach for software architectures can be:

-  **Horizontal** scalability (scale out): add or remove nodes to a system.

-  **Vertical** scalability (scale up): add or remove resources to a node in a system.

  
&nbsp;
### Reliability

Also known as Mean Time Between/To Failures or **MTBF/MTTF**. This requirement refers to the consistency in the anticipation of software operations. Therefore **unreliability** is the result of unanticipated results of software operations.

  

A common metric to measure reliability is the number of **software faults** (known as **bugs**), expressed as faults per thousand lines of code.

  

The best way to mitigate bugs in software is to do good **testing strategy**, therefore a software architecture easy to test could be more reliable than other architecture harder to test.

  
&nbsp;
### Concurrency

Concurrency refers to the capacity of handle **multiple computations** executing simultaneously, and potentially interacting with each other.

  

A software architecture with high concurrency have clearly identified parts that can execute concurrently. E.g. a [Pipe and Filter software architecture](https://www.arquitectosoftware.com/docs/pipe-and-filter/) with multiple **pipelines** at the same time will be more concurrent than a [Batch Sequential software architecture](https://www.arquitectosoftware.com/docs/batch-sequential/) that execute tasks in **batches**.

  

Concurrency also refers to the minimum, average and maximum number of **simultaneous users** using the software.

  
  
  &nbsp;

### Performance

  

Performance refers to the **amount of work** accomplished by a system and means the limiting factor in the end usability of the system.

  

Is totally dependent of the needs of the project, but good performance involves **different means**:

- For UI refers to a **low latency**, less execution time.

- At server code refers to **high throughput**, that is the rate of processing of work.

- In embedded architectures refers to low utilization of **computing resources**.

A [Blackboard software architecture](https://www.arquitectosoftware.com/docs/blackboard/) has a good performance because all listeners and subscribers in this architecture can work in parallel.

  &nbsp;

### Security

  

Security is a process of risk management that balances likely **security risks** against the **cost** of guarding against them.

  

This requirement allows the owners of resources in the system to **reliably control** who can perform what actions on particular resources. It implies many actions, some of them:

  

- Sensitive **resources** identification and protection: permission evaluation over every action over every resource.

- Identification and **authorization**.

- **Availability** protection.

- Secure **libraries**.

- Security **administration**.

- Information **integrity**.

- Continuous **monitorization** of vulnerabilities and threats.

  

A [Broker software architecture](https://www.arquitectosoftware.com/docs/broker/) implies more security challenges than a [Client Server architecture](https://www.arquitectosoftware.com/docs/client-server/) because the inherent networking complexities.

  
&nbsp;
### Availability

  

Availability is the capacity of a software architecture to be **fully or partially operational** when is required, and to effectively handle failures that could affect it.

  

Some tactics and actions related to availability:

  

- High-Availability hardware and load balancing.

- Fault-tolerant software.

- Component replication.

- Zero downtime deployments.

- Design for failure.

- Backup and disaster recovery solutions.

  

A service oriented architecture like microservices can use **load balancing** between instances and ensure more availability than a client server architecture with server as a **single point of failure**.

  
  &nbsp;

### Simplicity

  

Simplicity implies reduce responsibilities through **software decomposition** and separation of concerns using clear **interfaces**. The main goal of simplicity is to reduce complexity, this contributes to more maintainable and less costly systems.

  

A well-known rule is **KISS (Keep It Simple, Stupid)**, that states that most systems work best if they are kept simple rather than made complicated. Designing simple solutions is often a foundation to providing all other system qualities.

A **centralized architecture** will be more simpler than a **distributed architecture** because the inherent communications that distributed environment requires.

  &nbsp;
 
### Reusability

  

Reusability in software architecture refers to the degree in which parts of the architecture can be used in other software systems. It brings **cost reduction** due to the reuse of known and tested software components.

  

[Service Oriented architecture](https://www.arquitectosoftware.com/docs/service-oriented/) is a good candidate for reusability, e.g. a **microservice** can be reusable in different systems.

  
&nbsp;
### Flexibility

  

**Flexibility** refers the ability for the software architecture to adapt to possible or future changes in its requirements. A software architecture is flexible when its parts have **low coupling**.

When a system can evolve with only adding things, it says that system is **very flexible**. Conversely, if it is needed to change architecture parts in order to evolve it, then it's not flexible.

  

[Layered architecture](https://www.arquitectosoftware.com/docs/layered/) brings a lot of flexibility because parts of architecture are **clear separated** and can be evolved.

&nbsp;
### Portability

  

**Portability** in software architecture refers to degree in which the same architecture can be usable in different environments.

  

One key factor element of portability is a clear abstraction between **business logic** and system **interfaces**.

  

[Layered architecture](https://www.arquitectosoftware.com/docs/layered/) is very portable because parts of it architecture are **clear separated** and can be separated to another environment. Conversely, [Blackboard architecture](https://www.arquitectosoftware.com/docs/blackboard/) is less portable because of dependency between data store and its agents.

&nbsp;
### Testability

  

**Testability** refers to the degree to which a software part of architecture supports testing in a given test context. High testability implies more facility to find software faults or bugs, that improves reliability.

  

[Batch Sequential](https://www.arquitectosoftware.com/docs/batch-sequential/) is a very good candidate for testability because provides simpler divisions on subsystems that can be **tested separately**, using mock data between them.

  
&nbsp;

### Maintainability

  

**Maintainability** is about how easy the software system can be modified to correct faults, improve performance, or other attributes, or adapt to a changed environment.

  

These are some **metrics** used to measure maintainability:

- Technical debt.

- Code smells.

- Cyclomatic Complexity.

- Source Lines Of Code (**SLOC**)

  

Besides that, a key factor to ensure maintainability is **Mean Time To Repair** (MTTR), the average time required to repair a specific item or component from notification of a failure until to return it to working status.

  

In **Continuous Integration** cycles **static code analysis** are executed in order to measure previous metrics, [SonarQube](https://www.sonarqube.org/) is a good option to do it.

  

[Layered architecture](https://www.arquitectosoftware.com/docs/layered/) is a good candidate for maintainability due to separation of concerns.

  
  
&nbsp;
&nbsp;

## Conclusion

  

In this post is explained what are requirements in software engineering, and **Non Functional Requirements** at a deep level.

  

There are **software architecture styles** that performs better than others for a specific non functional requirements, therefore its crucial to evaluate a style for all of them before to select the best style for a project.

  

There are a lot of **Non Functional Requirements** to take in account, but the most important are: supportability, usability, lifetime, cost, scalability, reliability, concurrency, performance, security, availability, simplicity, reusability, flexibility, portability, testability and maintainability.

  

[Arquitecto Software](https://www.app.arquitectosoftware.com) makes this process automatically, evaluating Non Functional Requirements against architecture styles and showing which one is the best option.

Post also published on [Medium](https://medium.com/@arquitectosoftware/non-functional-requirements-the-pillars-of-a-solid-software-architecture-98657e2c0f2e).