Contents > 8 Defining Custom Design Metrics and Rules > 8.7 Defining Metrics for Profiles > 8.7.6 Extension References with Inheritance

8.7.6 Extension References with Inheritance

For the purpose of defining design metrics and rules, it is still cumbersome to have two model elements in the model to logically represent a single element. Consider for example metric "NumCls" for packages to count the number of classes in the package. This is the definition of the metric that ships with SDMetrics ever since its first release in 2002:
<metric name="NumCls" domain="package">
  <projection relation="context" target="class" />
Applied to our sample package with four requirements, this metric will include the class elements to represent the requirements in its class count. Depending on our measurement goals, this may not be what we want. We could of course adjust the definition of the metric to only count classes that do not represent requirements:
<metric name="NumClsExceptRequirements" domain="package">
  <projection relation="context" target="class" condition="Reqmt=''"/>
This approach is possible, but ugly. If we add support for SysML blocks or other types that also extend "class", we would need to adjust the definition of metric again to exclude classes representing blocks, etc.

To better deal with these issues, SDMetrics provides a mechanism to merge the extended element with its extending element to form a single model element that combines all the information from both elements. To enable this mechanism, we have to define the type of the extending element as a subtype of the extended element.

In our SysML requirements example, we therefore change the definition of type "requirement" by declaring its parent to be type "class":

<modelelement name="requirement" parent="class">
  <attribute name="base" type="extref" />
  <attribute name="text" />
  <attribute name="reqid" />
If SDMetrics finds a model element of type t ("requirement" in our example) with an extension reference, and the type of the extended element is a supertype of t ("class" in our example), then SDMetrics will merge the two elements into one element of type t. The merged element copies all attribute values of the extended element, and the extended element is removed from the model. We are left with one element of type t that assumes the place of the extended element.

Applied to our sample model and XMI file, we end up with a model that contains four requirement elements, no classes, and maintains the expected containment hierarchy:

Model "Sample"
  Package "Specifications"
    Requirement "XZY" with Id "R1"
    Requirement "ABC" with Id "R2"
      Requirement "A" with Id "R2.1"
      Requirement "B" with Id "R2.2"
The package "Specification" no longer contains elements of type "class", and metric NumCls will yield 0. Model element type "requirement" has become a full, first-class citizen. We can identify requirements simply by the type of the model element, the need for helper metrics is eliminated.

Using reference extensions with inheritance, it is very easy to define metrics that take more complex relationships into account. For example, the SysML defines a relationship "satisfy" to identify the model elements that fulfill a given requirement. The more elements are needed to satisfy a requirement, the more difficult the requirement will be to change. We are therefore going to define a metric that counts the number of elements that satisfy a requirement.

Technically, the SysML defines the "satisfy" relationship as a stereotype that extends the meta-class "abstraction". We therefore create a new model element type "satisfy" with an extension reference as a subtype of "abstraction" (see Appendix A.2 "Metamodel for UML 2.x"):

<modelelement name="satisfy" parent="abstraction">
  <attribute name="base" type="extref" />
The type "satisfy" inherits the multi-valued reference attributes "client" and "supplier" from "abstraction". For the XMI transformation, we only have to provide a trigger for the new extension reference "base":
<xmitransformation modelelement="satisfy" xmipattern="sysml:Satisfy">
  <trigger name="base" type="attrval" attr="base_Abstraction" />
We can then define our metric to count the number of elements that satisfy a requirement:
<metric name="Satisfiers" domain="requirement" category="Coupling (export)">
  <description>The number of elements that satisfy this requirement.</description>
  <projection relation="supplier" target="satisfy" sum="size(client)"/>