The Cisco DEVCOR Certification does a great job ensuring that we understand the core principles around excellent software design practices. You will find yourself reviewing best practices for software design around important aspects like scalability, high availability, and maintainability. With that said, let’s take a close look at a key first step in designing for maintainability.
A key step early on when designing a software solution is to evaluate what approach you should take to the problem. This is often a decision where you will land upon a certain design pattern.
A very common and powerful method of evaluating the design you intend is to consider it against the functional and non-functional requirements you face. Functional requirements specify what the software in question should do. On the other hand, nonfunctional requirements tell you how a system should perform those actions.
Functional requirements describe the required actions of a system. This might be some business process, or data manipulation, or user interaction. I could go on and on here since this would include any other action that the system can perform.
You will notice (if you are doing it right) that functional requirements can often be measured in “yes” or “no” terms and these requirements usually include the words “can” or “shall.”
Here are some example functional requirements of a Web application GUI you might be designing:
- Users can access a map of the network topology
- Users can add new notes to network devices
- Users can save configurations to a local drive
- Users can save configurations to a cloud drive
- Users can restore configruations back to a previous version
- The administrator can create and delete users
- Configurations can be sent to other users
Functional requirements are often derived from what we call user stories. User stories are short descriptions of functionalities, as seen from the end-user perspective. They focus more on how the user interacts with the system and what they expect the goal of the interaction to be, rather than what the system does.
Another tool we like to call upon is called a use case. A use case focuses less on the user’s interaction and more on the cause and effect of actions. For example, you might have a user story describing the pressing of a button to Create a Template, but the use case might provide much more details on exactly what occurs when this button is pressed.
Remember these best practices when it comes to defining your functional requirements:
- Be very concise and to the point.
- Avoid vagueness.
- Ensure your solution is testable.
- Clearly define who is allowed to perform certain actions or access data.
- Fully cover every scenario, including what the system should not do.
- Include complete information about information going into or out of the system.
- Contain only a single functionality.
When gathering requirements, consider the business, administrative, user, and system requirements:
- Business requirements – high-level requirements from a business perspective, such as the users being able to log in with credentials from the corporate network with the corporate network credentials passed through
- Administrative requirements – take care of routine actions, such as logging the changes that are made to some database by the application
- User requreiements – describe the rewquiremetns of your user proporulation, such as the ability to share documents that are created
- System requirements – these describe software and hardware specifications, for example a specific message that is returned when a user attempts to access a document they do not have permissions to read
I like to think of non-functional requirements as the quality attributes for the solution I am designing. Notice that nonfunctional requirements often use the words “must” and “should” and are commonly measured over an interval or a range.
Here are a few examples of non-functional requirements:
- The system must support at least 100 concurrent users
- The system should be available at least 99.999% percent of the time
- Users are required to register before they can use the system
- Passwords must not show anywhere in storage or logs
- The GUI system can be translated into all other languages
- The GUI system should fully load in under 3 seconds
A key for success in the design and your app are to use very specific language with your nonfunctional requirements. Notice here you would not say something like the GUI must load fast, you would instead say “the GUI must fully load in under 3 seconds.”
Nonfunctional requirements specify the quality attributes or technical requirements of the system.
They are more related to the system’s architecture than its functionalities and are often constraints on the technical properties of a system. To ensure maintainability, we will often design excellent internal testing mechanisms to ensure that non-functional requirements are being met or exceeded.