3.9. Value Types
Like a block, a value type is an element of definition—one that generally defines a type of quantity. I say “generally” because there are two value types in SysML—Boolean and String—that arguably are not quantities.
You can use a value type in many places throughout your model. Most often, it appears as the type of a value property, which is a kind of structural feature of blocks. (Section 18.104.22.168, “Value Properties,” has more details.) But that’s not the only place where value types make an appearance; they’re actually ubiquitous in system models. They can also appear as the types of the following:
- Atomic flow ports on blocks and actors
- Flow properties in flow specifications
- Constraint parameters in constraint blocks
- Item flows and item properties on connectors
- Return types of operations
- Parameters of operations and receptions
- Object nodes, pins, and activity parameters within activities
There are three kinds of value types—primitive, structured, and enumerated—that you typically define in your system model. A primitive value type has no internal structure (it doesn’t own any value properties). Its notation is a rectangle with the stereotype «valueType» preceding the name.
SysML defines four primitive value types: String, Boolean, Integer, and Real. You can, of course, define your own primitive value types as specializations (subtypes) of these four. For example, Figure 3.25 shows three value types (º, V, and º C) that are subtypes of Real.
Figure 3.25 Value types
As its name implies, a structured value type has an internal structure—generally two or more value properties. As with a primitive value type, the notation for a structured value type is a rectangle with the stereotype «valueType» preceding the name. SysML defines one structured value type: Complex. Its structure consists of two value properties—realPart and imaginaryPart—that are both of type Real. One structured value type may, in turn, be the type of a value property within another structured value type. In this way, you can create arbitrarily complex systems of value types.
An enumerated value type—colloquially called an enumeration—simply defines a set of literals (legal values). If a parameter of an operation (or some other kind of element shown in the earlier bulleted list) is typed by an enumeration, then the value it holds at any moment must be one of the literals in that enumeration. The BDD in Figure 3.25 shows an enumeration named CommandKind, which defines two literals: Stored and Real-Time. I could use this enumeration, for example, to type an input parameter named kind in an operation named buildCommand. When a client calls this operation (within a running system), the only legal values it can pass are Stored and Real-Time.
I mentioned earlier that value types can be related to one another by using generalizations. A value type hierarchy can be arbitrarily deep, and generalizations—as you may recall—are transitive. For example, Figure 3.25 conveys that the value types VDC and VAC are (indirectly) subtypes of Real. The principle of substitutability applies here just as it does in the case of generalizations between blocks: Values of type VDC and VAC will be accepted wherever their supertypes (V and Real) are required. These supertypes are abstractions. And the principle of designing to an abstraction—and its consequent extensibility—also applies to this practice of creating a value type hierarchy. This is a widely used and powerful modeling practice.