In the Using DITA to Automatically Assemble Requirements Documents, I explained how DITA can help you flexibly and automatically manipulate requirements by decomposing and aggregating various pieces of content differently for different contexts.

Today I’m going to talk about reusing requirements and how DITA can help here. So here comes Reason #2:

Reason #2: DITA Lets You Reuse Requirements

Requirements reuse has become a topic that is being widely discussed by software engineering experts. For example, just recently I’ve read a very interesting article about software requirement patterns. The main idea is that all project-specific elements are eliminated and converted into patterns. Patterns are stored in a catalog from which you can pick up patterns required for a specific requirements document.

It’s so much about DITA. As you know, DITA lets you reuse requirements on multiple levels.

Reusing an Entire Requirement

Too often, in addition to requirements that are specific for a particular project, you need to include a requirement which is common for all projects of this type. For example, if you are developing apps for mobile devices, there might be a requirement saying that the app has to run on iOS, Android, and Windows Mobile. This requirement should be included into the requirements documentation of all your apps.

In DITA, it means that you need to make sure that the topic with this requirement is added to all maps. This works very well together with the ability to assemble documents automatically discussed in the previous post. Because the content is structured, you can define a logic for automated assembly of requirements documents, so that the desired standard requirements will be picked up and added to maps automatically.

For example, if you provide metadata for maps and topics so that the content can be found and retrieved by metadata categories, a certain set of standard requirements can be automatically added to a map based on the type of the product or project.

 

Reusing Requirements with Variable Content

There might be a few use cases when you want to reuse a requirement, but some parts of the requirement have to be changed depending on the project.

Handling Variables in Requirements

One use case is when you want to reuse a requirement that is generic for multiple projects, but include some variables. For example, you are developing an enterprise storage system that you sell to corporate customers. Depending on the customer, the amount of information that can be stored in the system varies.

In DITA, the customer-specific amount of information can be represented by a variable. You can handle the variable using the keyref mechanism.

Let’s say that the Customer A should be allowed to store 100 Terabytes while Customer B should be able to put 500 Terabytes into the system. You create a separate map for each customer and add the <keydef> element. Its @keys attribute represents the name of the variable. In each map, the value of the variable represented by <keyword> will be different.

From each of these maps, you also refer to the topic that describes the requirement itself, InformationAmount.dita.

 

Requirements_CustomerA.ditamap

<map>

<title>Requirements for Customer A</title>

<keydef keys=”InformationAmount“>

<topicmeta>

<keywords>

<keyword>100 Terabytes</keyword>

</keywords>

</topicmeta>

</keydef>

<topicref href=”InformationAmount.dita “/>

</map>

 

Requirements_CustomerB.ditamap

<map>

<title>Requirements for Customer A</title>

<keydef keys=”InformationAmount“>

<topicmeta>

<keywords>

<keyword>500 Terabytes</keyword>

</keywords>

</topicmeta>

</keydef>

<topicref href=”InformationAmount.dita “/>

</map>

 

In InformationAmount.dita, you refer to InformationAmount through the @keyref attribute:

InformationAmount.dita

<concept id=”concept_yr1_cy3_xs”>

<title>Information Amount</title>

<conbody>

<p>The amount of information that can be stored in the system is <ph keyref=”InformationAmount”   />.</p>

</conbody>

</concept>

Depending on the map from which you generate an output, the InformationAmount variable will be resolved to either 100 Terabytes or 500 terabytes.

And again, if you provide metadata for the maps and the topic, the variable value can be resolved automatically based on the type of the product or project.

 

Handling Variable Portions of Content within Requirements

Let’s say that you want to add payment terms to each proposal:

  1. After the project is completed, the Company will issue a pro forma bill.
  2. The payment term is immediate payment.
  3. After the payment is received, the Company will issue the tax invoice.

While items 1 and 3 are common for all customers, item 2 might vary depending on a specific customer. For example, some customers pay immediately after receiving the bill while some of them pay under the NET+30 term. DITA lets you create separate topics so that each topic would contain a certain payment term, refer to the topic through the @conkeyref attribute, and resolve the key to the topic required in each particular case in the map.

For example, PaymentTermOptions_Immediate.dita contains the term for an immediate payment.

PaymentTermOptions_Immediate.dita

<concept id=”concept_ub1_lrd_xs”>

<title>Payment Term Option</title>

<conbody>

<ol>

<li id=”payment_term”>The payment term is immediate payment.</li>

</ol>

</conbody>

</concept>

 

Another topic, PaymentTermOptions_NET30.dita, contains the term for a NET+30 payment.

PaymentTermOptions_NET30.dita

<concept id=”concept_hwp_rrd_xs”>

<title>Payment Term Option</title>

<conbody>

<ol>

<li id=”payment_term”>The payment term is NET+30 days after the day the pro forma bill is submitted.</li>

</ol>

</conbody>

</concept>

 

In PaymentTerms.dita, you define the common terms and pull the payment term required in this particular case using the conkeyref.

PaymentTerms.dita

<concept id=”concept_bzd_hsd_xs”>

<title>Payment Terms</title>

<conbody>

<ol>

<li>After the project is completed, the Company will issue a pro forma bill.</li>

<li conkeyref=”term/payment_term“/>

<li>After the payment is received, the Company will issue the tax invoice.</li>

</ol>

</conbody>

</concept>

 

Finally, in the map that represents a specific proposal, you resolve the key “term” into the location of the topic that contains the payment term you need for this particular customer.

Proposal_CustomerA.ditamap

<map>

<title>Proposal for Customer A</title>

<topicref href=”PaymentTermOptions_Immediate.dita” keys=”term” processing-role=”resource-only”/>

<topicref href=”PaymentTerms.dita”/>

</map>

 

For another customer that pays you under the NET+30 term, you build another map that refers to the same PaymentTerms.dita, but you resolve the key “term” differently.

Proposal_CustomerB.ditamap

<map>

<title>Proposal for Customer B</title>

<topicref href=”PaymentTermOptions_NET30.dita” keys=”term” processing-role=”resource-only”/>

<topicref href=”PaymentTerms.dita”/>

</map>

 

Since the process of assembling a map can be automated as I wrote here and here, the key can be resolved into the actual file name, for example, depending on certain parameters, such as type of the customer or project.

(Theoretically, you can also achieve the same goal by using conditional content, but as the number of content variations grows, eventually this might cause an overhead).

In the next post, I’m going to discuss an ability of DITA to enforce consistent structure to your requirements documents. As part of this feature, we’ll also talk about a higher level of requirements reuse, when the structure of an entire document can be reused for multiple projects or products.

Leave a Reply

Your email address will not be published. Required fields are marked *