Before you continue reading this post, please answer the following question:
“Is a square a rectangle?”
This is apparently a very simple question, to which we should be able to answer almost immediately, without even thinking about it.
However, if you try asking different people, you will discover that they disagree. Some are absolutely convinced that a square is a kind of rectangle, while others are sure that squares and rectangles are completely different geometric figures. It may be particularly interesting to ask children, and see that most probably they will be very surprised with this question.
Now let’s say that you think that a square is a rectangle, while a co-worker believes that a square is not a rectangle. How will you be able to convince him that you are right? How can you explain to him why do you think that a square is a rectangle?
The answer is that you must first agree on the definitions of what is a square and what is a rectangle. These are some possible definitions:
- Rectangle: A four-sided plane figure with four right angles.
- Square: A quadrilateral having all sides equal, and its interior angles all right angles.
From these definitions, it is clear that a square is a special kind of rectangle that happens to have all sides equal. Therefore, if you and your co-worker agree with these definitions, you will also agree that a square is a rectangle.
It happens very often that people working together are not able to agree on some decision simply because they did not make an effort to clarify and agree on the basic definitions of the problem being discussed. Of course this happens in software development projects as well.
Having clear and precise definitions is particularly important in the system requirements specification phase. Most systems have two types of requirements: functional and non-functional.
Functional requirements describe the business logic that the system must implement. Today we have learned how to define functional requirements in details, using relatively formal tools such as use-cases and sequence diagrams.
Non-functional requirements describe the expected system performance. They include technical parameters such as latency and throughput, as well as system attributes such as scalability and robustness. Unfortunately, it happens frequently that non-functional requirements are not given the attention they deserve.
For example, suppose that you are developing a server-side system, and that the specification requires it to be able to handle at least 400 transactions per second (TPS). At first glance, this seems to be a well-defined requirement: It gives you a precise number. However, it is in reality a very problematic definition.
In any interesting system there are different kinds of transactions with diverse complexities. In client-server systems there will probably be login and logout requests. Logout should be a simple request, implemented by updating the user status and doing some clean-up. Login, in contrast, may be much more complex, requiring authentication and authorization. The required TPS is only meaningful if you know how the different types of transactions are mixed together.
Assume that this is the expected transaction distribution of your system:
- Login: 5%
- Create record: 10%
- Read record: 40%
- Update record: 30%
- Delete record: 10%
- Logout: 5%
Now the requirement of 400 TPS is much more meaningful. You know exactly how many transactions of each kind you should expect. If for some reason the system is not efficient enough to handle 400 TPS, you know that the two more frequent types of requests are responsible for 70% of the traffic, so that they should be the first candidates for optimizations. The QA team should now be able to develop automatic tools that reproduce real world load, and test the system under stress.
Without clear definitions it is very easy to implement a rectangle when you should be implementing a square…