From the course: Software Design: Developing Effective Requirements

Functional vs. non-functional

- There are several ways to understand the difference between functional and nonfunctional requirements. One way is that functional requirements represent what the system should do. For example, in our university events scheduling system, it should auto-populate student's schedule from academic calendar. It should generate alerts and so on. They represent the business process that is being automated. Nonfunctional requirements, on the other hand, represent how the system should do those tasks. Should auto-population be fast or should generating alert be fast. Your answer would be, "Well, all functionalities should be fast." Similarly, should the interface for viewing schedule be user-friendly? How about for checking any schedule conflicts? Once again, your answer would be, "UI for all tasks should be user-friendly." So the point here is that nonfunctional requirements cut across functional requirements. All functional requirements need to support the nonfunctional requirements. Another way to look at the distinction between functional and nonfunctional requirement is to see who they concern. Functional requirements are what users are concerned about and you will get to know about them when users articluate them. You can always ask the user about what they want. Functional requirements represent the domain knowledge and that is what business analysts focus on. On the other hand, nonfunctional requirements pertain to system properties such as reliability or supportability. Users assume that the system will have those properties without explicitly asking for them. But for architects, knowing exactly which nonfunctional requirements are expected plays a critical role in defining the underlying architecture of the system. As an example, if you want the schedule conflicts in the university events scheduling system to be shown in real-time with delay less than two seconds, then the architecture of the system will be very different from what you would need to generate an offline conflict report at the end of the day. Nonfunctional requirements drive the system architecture and these requirements manifest broadly in two ways. Quality and constraints. Think about quality in terms of the system properties as designed from within. Constraints, on the other hand, are imposed from factors outside the system. Quality can once again, be expressed in two ways. External or internal. External properties are evident when the user uses the system. Is it usable? Reliable? Available? And so on. Internal quality, on the other hand, is what developers and architects focus on. How do I design it so that I can scale it to 10,000 users next year? Or how should it be designed so that it is platform agnostic? Constraints are some kind of restrictions imposed from outside the system. For example, the kind of hardware or software you can use. Data that is coming from another application that needs to be read. Other systems that your system must interact with, and so on. For example, the university events scheduling system needs to interface with the central authentication system and so the architect needs to figure out how to make that happen. Nonfunctional requirements, as I said, are often not articulated by the users. They're mostly assumed by them. So let us say, I ask a university staff member what kind of usability they want from the events scheduling system. Most likely, their answer would go something like, "Gimmie a system that is easy to use." That does not help much, does it? So, how do we know which nonfunctional requirements to consider for our system? The solution is to use a ready-made taxonomy of nonfunctional requirements as a starting point. You may find such taxonomies, or a list of nonfunctional requirements from sources, some of which are listed here as an example. The OpenUP repository has a template called Supporting Requirements Specification that could be a good starting point. Or you can refer to one of the most well-known books on software requirements by Karl Weigers that has a full chapter devoted to nonfunctional requirements and lists many of them to start with. Karl has also referenced the third resource listed here which is a short document summarizing the taxonomy of nonfunctional requirements. These taxonomies will give you a fairly long list to start with. So the next step is to reduce it by removing those requirements that are not relevant for your application. For example, if you are not planning to port your application to another platform in your future, then portability can be removed from the list. Next, you need to prioritize the most important ones especially if some of these requirements conflict with each other. For example, trying to make an application portable to multiple platform often negatively impacts its usability. So, here you need to decide. Which one is more important, portability or usability? Similarly, making a system secure through authentication, encryption, and malware scanning makes it slower and sometimes even less usable Again, which one is of higher priority? Performance, security, or usability? When you try to prioritize you may have to get a little more specific about these requirements and that brings us to the last step, quantify and specify. Quantifying these requirements not only helps prioritize but also makes them concrete and testable. Let us look at an example. Let us say we identified three functional requirements as listed here. Now, to be specific, we can say for performance that the response time for each page display or refresh should take less than two seconds. Availability should be 99% between 6 a.m. to 9 p.m. on all days. And for usability, a standard template should be used. For example, the UI standard for Android or iOS platform. And we can also get even more specific by saying that the UI should provide helpful tips and features such as autocompletion and correction.

Contents