The scope definition document consists of types
and methods (aka “use cases”). For example, there are two types
(Visitor
and Image
) and one
use case (UC3.2
) defined in the snippet:
Anything inside double quotes is considered as informal content, which we take “as is”, without any attempt to understand what it means. You can double quote anything (except double quotes, of course), and you can place informal texts in any place of the document. They are ignored during formal Requs analysis.
Let’s consider a bigger example of a type Image
:
The semantic is the same – the type still contains three slots
(PNG content
, name
and size
). However
in this example we added an informal explanation to every one of them.
An as
keyword separates the name of the slot and its invariant.
Pay attention to the dots, colons, semicolons and commas used above.
Comma, semicolon and preposition and
can replace each other.
For example, the following declarations are semantically equivalent:
By means of is
/is a
we enable a declaration of invariants
on types. Invariant is a predicate, which is always true, no matter
what happens with the system. In the example above it is always true
that PNG content
is a file with binary content (not a readable
ASCII text). Nobody can break this invariant and put a textual information
into this slot.
As you noticed, an invariant can be declared with an informal text, as we’ve
done with size
. Such a declaration means
absolutely nothing and will be ignored. But it helps when you’re starting
to develop the SRS document.
In general, informal texts play an important role during the initial development of a requirements document and during a preliminary system analysis. When you don’t know for sure how to define the information you have in a strict format – you should use informal texts. Later, when you have more information, you will replace them.
Requs is a case-insensitive language in all places
except one – type names should use
CamelCase Notation. Thus,
File
, ImageFile
, and VeryBigImageFile
are valid type
names, while imagefile
is just an English word.
To put things together we should declare a use case, which is a step-by-step explanation of interaction between instances of types (so called objects), for example:
First line in this example is a declaration of a use case,
which number is UC8.1
. The use case has a signature,
which differentiates it from all other use cases. It is not the
ID of the use case, but the signature, which is important. This
concept is very similar to
function signature
in programming. The signature of this use case is:
In order to include this use case into another one we should use this
signature, filling it with particular objects. Objects start with
article the
. On their first occurrence they appear in round brackets
and start with a
or an
.
In our use case there are three objects: the user
,
the friend
and the photo
. An object could be
either received by a use case or created inside it. However, there is no grammar
difference between objects received and objects created. We assume
that an object is empty until anyone updates or creates it (more on this later).
There are seven main flows in this use case, and five alternative
flows. Flows 1
, 5
, 6
, and 7
instruct us to include other use cases that match the signatures
provided and pass them the objects we have.
In the example above, one of the use case steps
mentioned using
operator:
This is similar to sending arguments to a method. In this line we’re calling a method “receives” on “the friend” object like this:
Instead of using
you can use of
or with
. These three
keywords are reserved and can’t be used as English words.
There are four use cases that are included by UC8.1
.
They have to be defined somewhere else in the document,
otherwise the document will be semantically incomplete. But not all four are
mandatory, because there is a number of elementary use cases,
which are defined in the system, even if the document is
empty. The elementary use cases are
(CRUD requirements pattern):
As you understand, something
means “object of any type”.
create
means making/instantiating of a new object.
read
means reading of all and any slots of an object, and all their slots, etc.
update
means changing of values of slots of an object.
delete
means removing an object from a persistent storage.
Thus, a valid flow either points us to another use case defined somewhere else in the document, or points us to an elementary use case, or points us nowhere with an informal text (informal flow).
Besides that, a flow might have a special instruction, which we’ve seen
in alternative flow UC8.3/1
and UC8.3/3
. fail since
means that a use case should be stopped at this point and the
reason of this termination is explained right after the word since
as an informal text.
Reason of failure is used by a parent use case, which included the
current one. This is exactly what happens in UC8.3/3
. We are
waiting for a failure from we convert the photo
, and
we’re ready to accept a failure called invalid format
.
This approach is very similar to
exception handling paradigm
in object-oriented languages.
There is only one metric that tells us everything about the entire scope definition document. The metric is called “scope ambiguity” and is calculated like:
S
stands for a total number of all informal flows,
and M
is a total number of CRUD-manipulators.
Thus, if A
equals to 0, the document is absolutely non-ambiguous,
which is an almost impossible situation. In real world projects
the task of a system analyst is to move A
from 1 to 0.
A slot may have an “arity”, determined by a suffix attached to its name. There are four possible options:
-s
means “one or many” or 1..*
in UML.
-s?
means “zero or many” or 0..*
in UML.
No suffix means exactly one, or 1
in UML.
A slot without a type means composition. A slot with a type means aggregation. In order to make a slot with a type of composition nature, you should use an exclamation mark after the type:
Any type can be an actor, just say so in your spec:
Only actors can perform read
operations.
Any use case may have attributes assigned to it. Attributes may be used, for example, for requirements prioritization.
You can “seal” your statement with a hash code:
This hash code af63e2
is calculated from the content of UC3.2
.
If the content is changed, this statement becomes invalid and the entire
document can’t be compiled any more.
More about it in Attributes and Seals.
To any use case you can add a number of non-functional requirements (NFR), in the following format:
After the name of the use case you put a forward slash and then a mnemonic name of a non-functional requirement. Then, you put “must be” and an informal text.
More about it in Non-Functional Requirements.
Sometimes you may need to add informal pages to your SRS document. For example, Vision, Business Case, wireframes, UI mockups, tables, research results, supplementary tables, etc. The syntax is simple:
Page name should be in CamelCase, as well as type name.
Read on Markdown syntax.