For decades, requirements have been written primarily using natural language. There are many good reasons for this, as we already explained in this series. Modeling requirements has been used in the past as well, but not in a standardized manner.
Modeling in the Old Days
Before systems modeling was standardized, people still used models. Models include, well, physical models, like the body of a ship’s hull. Prototypes and mock-ups are other examples of physical models. And as long as engineers can remember, models were created on paper, in the form of sketches, flow diagrams and the like. Some of these models were informal and meant to be thrown away, others used a more formal notation and were maintained throughout the system development life cycle.
Unified Modeling Language
But the real break-through came with the development of the unified modeling language (UML). For those who don’t know it: UML is a graphical general-purpose modeling language that covers the structural and behavioral aspects of a system. In a nutshell, it formalizes the use of “boxes and arrows” to give them a well-defined syntax and semantics. There are plenty of primers on UML online.
Wikipedia has a nice picture that shows the convergence of the various proprietary modeling languages into a publicly standardized unified modeling language. Being standardized and having no strings attached allowed UML to quickly gain broad acceptance.
Before anybody complains about the formality of UML (or the lack thereof), I’d like to point out two things: First, UML can be used as formally or informally as one likes (even some would sniff at the use of UML for mere “painting”); Second, later in this series I will talk about “real” formal languages, and how far UML can be pushed in that direction.
Methods for UML Requirements Modeling
The success of UML also has a downside: Over time, it grew into a huge behemoth, and the size of the standard (and the thickness of the UML books in the bookstore) can be intimidating. Therefore, for any task at hand, the relevant subset of UML should be identified. Also, UML is a language. Like the language we speak, it can be used in many different ways, good or bad, and even incorrectly. A method describes how the language should be applied. This typically also addresses the issue of limiting the UML elements to be used.
Many organizations develop or adapt their own methods. If nothing is in place yet, it’s always a good idea to start with a method that is as close to what’s needed as possible. That method can then be adapted for the organization or project in question.
Most methods use UML use cases (UC) to describe the high level requirements, and UML class diagrams to describe the domain. From there, the model is refined to add more detail. How this looks like in practice is described below. But first, here are two methods (out of many others available) that provide a good starting point for UML requirements modeling:
- ICONIX is a lightweight method from the 90ies. It promised to get from requirements to code with only four UML diagrams. For whatever reason, it is not very widely known. I consider it very useful for small and medium-sized software projects that are not safety-critical. I wrote about ICONIX in SE-Trends, my German blog.
- SYSMOD is more of a toolbox than a method, but it contains a number of useful tactics for requirements modeling. A SYSMOD-based methods has been described by Tim Weilkiens in various books. For a good introduction I recommend the (slightly older) Systems Engineering with SysML/UML.
UML Requirements with Use Cases and Class Diagrams
In UML, requirements are typically captured in Use Cases (UC). A use case shows the interaction of a user with the system and can be usually be captured in one sentence. E.g., “As a user, I want to log out of the system, so that nobody can access my account from this browser session”. A use case should have an ID (e.g. “Logging out”). It’s possible to draw a picture of the use case, as shown below.
Correspondingly, the domain is modeled, replacing a traditional glossary. For this, UML Classes are used. These are much more precise than a glossary, showing well-defined relationships between classes, which can be enriched with attributes and operations.
Please: Use it Right!
The same way that the English language can be abused, UML can be used incorrectly. It is very easy to “paint” something that looks right, but has the wrong meaning. Therefore, let me plead here: Take your time to understand the meaning behind the elements you use. Whether a line is solid or dashed can make a huge difference in semantics.
Experienced users often frown when UML is “just” used as a drawing. In other words, when the model is not processed further. I have no problem with this, if it improves communication. The biggest problem I see here is that the author does not get feedback on the correct usage of the language.
The Diagram is not the Model
At first glance, UML seems to be all about the diagrams. But if done right, it is a byproduct of the modeling process, albeit a useful one. The diagram helps to grasp the “big picture”. It serves as a map, helping the reader to navigate the model. But each symbol in the diagram provides a lot of additional information that often has no representation in the picture. To demonstrate this, let’s look at the use case. The picture only show the identifier and the relation to the actor. The following table shows some of the information that may be part of the model as well:
|Actors||Any logged in user|
|Description||As a user, I want to log out of the system, so that nobody can access my account from this browser session.|
|Preconditions||User is logged into the system|
|Activity||[User] initiates log out [System] logs the user out of the system and displays a corresponding message|
|Postconditions||User is logged out of the system|
Correspondingly, The model of the class could hold attributes, operations, constraints and much more.
Getting more Formal
In the example, large chunks of the model are again informal. The preconditions and postconditions of the use case, for instance, are formulated in plain text. However, just by labeling them as constraints, value is added. For instance, a large number of test cases can be derived from the model, simply by engineering appropriate test scenarios for all constraints.
Further, UML provides a number of mechanisms for formalizing the specification. This is nicely done by ICONIX: The final product of the ICONIX method is software code. And code is arguably a formal model that can be executed to provide the desired functionality. ICONIX achieves this by refining the use cases into sequence diagrams (via robustness diagrams), adding detail on every step. Activity diagrams and state diagrams are other UML model elements that add detail and formality.
Last, there is the Object Constraint Language (OCL), a textual language that allows some of the informal elements to be stated formally, in a machine readable fashion.
Where are the Requirements?
One thing seems to be missing: Where are the requirements? They are still here, but took on a different form. Specifically, many model elements can be interpreted as requirements. For instance, they are easily recognized in the constraints (pre-, postconditions and invariants), but make only sense in the context of the model that they are embedded in. Therefore, the top-level model elements, like classes and use cases, do not directly correspond to individual requirements, but provide the context of many embedded requirements. This is actually a big advantage: In a textual specification, the context of the requirements can be hard to grasp, e.g. by deducting it from the chapter structure. In a model, however, the context is clearly defined. Again, looking at the use case example, the precondition is only relevant in the context of the use case “Logging out”. This also means that any changes to the specification outside the use case will not affect this precondition. This makes it easy to remove dependencies and to break down the problem into smaller chunks that can be worked on independently.
It is tempting to take advantage of all the UML has to offer, possibly even all the way to code generation. While this is possible, it is advisable to introduce UML for requirements modeling in small steps. There are many pitfalls on the way, and trying too much in the first steps can lead to failure and rejection by the stakeholders.
Having said that, UML requirements modeling is great for agile environments, as it makes it much easier to understand and limit the impact of changes. Therefore, I can only recommend to give it a try.
For groups already familiar with UML requirements modeling, increasing the formality can produce some benefits. It could also be interesting to increase the level of formality, especially in safety critical environments. We’ll talk about more formal requirements modeling in the near future.
Image source (modified): Joone via Flickr