I left this topic at the end of the test phase of generate and test. The generate phase still needs to be discussed. How does one generate the next hypothesis?
Generate next design hypothesis
The test phase will identify a list of four types of problems to be addressed in the next design hypothesis. These are a list of responsibilities not currently in the design hypothesis, a list of quality attribute problems with the current design hypothesis, a list of mechanisms to support the policies decided as a result of the view-specific use cases, and a list of constraints not satisfied by the current design hypothesis. I’ll begin by discussing quality attribute problems.
Quality Attribute Corrections
The basis for adjusting the current design hypothesis is to use tactics to transform it to improve the design hypothesis with respect to the quality attribute that was identified in the testing phase. There are two portions to this adjustment: choose a tactic and apply the tactic.
Choosing a Tactic
Each quality attribute problem resulted from the failure of the current design hypothesis to support a particular quality attribute scenario. For the quality attribute(s) specified in the scenario, various tactics can be applied. For each candidate tactic, the architect should consider the implications of applying it. The architect should ask following questions for each candidate tactic:
- Will this tactic improve the quality attribute behavior of the current design hypothesis sufficiently?
- Should this tactic be used in conjunction with another tactic for this quality attribute?
- What are the tradeoff considerations when applying this tactic?
Since these are the questions that will be asked during the testing phase, asking them at the point of choosing a tactic is an optimization. Asking them now, even without precise answers, will help to reduce the number of iterations required to achieve a satisfactory design.
Applying a Tactic
The tactic to be applied to the current design hypothesis will affect the properties, the structure, or the responsibilities of the current design.
- Properties. The properties of an element or a relation act as instructions for the implementer. For example, a communication channel may have a property of “encrypted, 128 bit AES”. This is an instruction to the implementer as well as an indication that the current design will satisfy a particular quality attribute scenario. For another example, a responsibility may have a property of execution time that has a specific value. This is an instruction to the implementer that the calculation of this responsibility is important to overall system performance and the bound must be achieved
- Structure. Tactics affect the structure in either explicit or implicit ways. An explicitly structural tactic such as “create an intermediary” assumes that the architect knows what elements the new module or component is an intermediary between. An implicitly structural tactic such as “authorize users” assumes that the architect knows that the users are to be authorized before executing particular functions. This tactic is structural because it makes assumptions about data flow and execution order. The architect must understand the structural implications of a tactic and then revise the current design hypothesis to reflect the inclusion of the applied tactic.
- Responsibilities. Every tactic that has a structural aspect also has additional responsibilities to be added to the design. For example, “create an intermediary” implies that there are responsibilities to enable the new element to perform as an intermediary. The architect should add the responsibilities that result from structural changes as the structural changes are made. Other tactics introduce responsibilities with no structural aspects. For example, the responsibilities that provide the ability to cancel may be located in a variety of different elements. The architect should treat these responsibilities in the same fashion as the responsibilities discovered as missing while exercising the important use cases.
Adding Additional Responsibilities
After performing the test phase and adjusting the current design hypothesis by applying tactics, the architect will have a list of responsibilities that have no predefined module to which they must be designed. These responsibilities must now be assigned to modules. Some guidelines for assigning responsibilities to modules are the following:
A List of Mechanisms
A mechanism to support the policies generated by considering the view-specific use cases is typically a tactic. That is, it should be treated as an additional tactic to be applied to the current hypothesis. Even if the mechanism is not a tactic, it still has the same characteristics in terms of properties, structure, or responsibilities. As a consequence, these mechanisms are treated in the same fashion as tactics.
A List of Constraints Not Satisfied by the Current Design Hypothesis
There are several options for dealing with the problem of a constraint not satisfied:
- Modify the design to accommodate the constraint. This may leave unsatisfied several other requirements, so this option must survive the next testing phase. Otherwise, the generate-and-test cycle will never converge.
- Report to the project manager that the constraint cannot be satisfied without jeopardizing other requirements. The architect must be prepared to justify such an assertion but, essentially, this is asking, “What is more important–the constraint or the other requirements not satisfied if I satisfy the constraint?”
Once the four types of problems have been considered, the design is ready to be tested again. As stated, the generate-and-test cycle continues until the results are good enough or until budget or time are exhausted. Then implementation begins.
Once implementation begins, problems with the current design will also be discovered, and these can be treated as test failures in the generate-and-test cycle.
– Len Bass, SEI