Like the preceding design phases, detailed design proceeds largely through the application of design patterns (also
referred to as design "idioms"). That is, for the most part, the problems you're trying to address in this
most-detailed level of design have been solved before in different systems and perhaps for different applications.
However, those solutions can be abstracted, generalized, and reapplied in new situations, including your current system
under development. The issues normally addressed during detailed design include:
-
Ensuring operation pre- and post-conditional invariants, such as
-
-
Range checking
-
Reasonableness checking
-
Unit checking (e.g. miles vs. kilometers)
-
Internal data structuring
-
Internal algorithmic structuring and optimization
-
Optimization of state machines
-
Specifying local error and exception handling (both accepted and thrown)
-
Low-level redundancy for safety and reliability
-
Numeric round off error management and correction
-
Abstraction of services into interfaces
-
Class feature visibility
-
Ensuring quality of service budget adherence for services
-
Realization of associations, e.g.
-
-
Pointers
-
References
-
Object IDs
-
Widget handles
-
Socket
-
…
-
Be sure to validate the class both in isolation and in the collaboration to ensure 1) the functionality has not
been broken with the changes and 2) the desired optimizations are achieved.
-
Data re-structuring attempts to optimize the class attributes in terms of the identified optimization criteria,
e.g. "read time" vs. "write time" or memory usage vs. pre-computation. One key concern is the selection of the
appropriate primitive representational type (e.g. int, short, long, or double), the acceptable sub range within
that base type and how the class will ensure the value(s) stay within the appropriate range as well as what to do
if they do not.
Operations hold the code for method functions of classes. While most methods are short (3-10 lines long), some may be
highly complex (e.g. "computeKalmanFilter()") and may need to be decomposed, possibly across multiple classes or parts
of the main class. This might be done just to manage the complexity of the algorithm (although if the operation is
complex, it is recommended that the operation be represented in an activity diagram and then code can be generated for
it), or to optimize the operation for initiation or execution time (e.g. worst-case performance, average performance,
read performance, write performance, predictability of performance, minimization of jitter, etc), safety, reliability,
or resource usage.
|