blob: 9f2ae3a0cfb398cd6205174a787af3f466efa2b2 [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<org.eclipse.epf.uma:ContentDescription xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI" xmlns:org.eclipse.epf.uma="http://www.eclipse.org/epf/uma/1.0.5/uma.ecore"
xmlns:epf="http://www.eclipse.org/epf" epf:version="1.5.0" xmi:id="-8V5osHpRNG6Z7KPy8RGW1w"
name=",_C4U9QPTeEduDKIuqTXQ8SA" guid="-8V5osHpRNG6Z7KPy8RGW1w" changeDate="2007-05-31T11:32:35.160-0700">
<mainDescription>&lt;h3> Review the design &lt;/h3>&#xD;
&lt;p> Design is best accomplished collaboratively, because it is a problem-solving &#xD;
activity with a range of&amp;nbsp;parts and perspectives. There should be a constant &#xD;
level of review to ensure that the decisions make sense within the area being &#xD;
designed and in the design of the system overall. There also might be occasions &#xD;
where some area of design is reviewed by a set of interested or knowledgeable &#xD;
parties, such as the architect who will verify that the design conforms to an &#xD;
architectural decision or a developer who will be expected to implement the &#xD;
design. &lt;/p>&#xD;
&lt;p> The design should be examined to ensure that it follows heuristics of quality &#xD;
design, such as loose coupling and high cohesion. Responsibilities should be &#xD;
appropriately distributed to elements in ways that there are no elements with &#xD;
too much responsibility and no elements that are left without any responsibilities. &#xD;
The design should be able to clearly communicate the design decisions, yet not &#xD;
delve into concerns best dealt with during implementation of code.&lt;/p>&#xD;
&lt;p> Ensure that the design follows any project-specific guidelines and conforms &#xD;
to the architecture. Modifications to the design to improve it (based on issues &#xD;
identified in reviewing it) should apply &lt;a class=&quot;elementLink&quot; href=&quot;./../../../openup/guidances/guidelines/refactoring_33F165CA.html&quot; guid=&quot;_OlyWoOX7Edu8VZPtlaU33g&quot;>Refactoring&lt;/a>&amp;nbsp;to &#xD;
ensure that the design and any existing implementation of the design continues &#xD;
to fulfill its responsibilities. &lt;/p>&#xD;
Revisit the relationships between elements to improve the coupling in the design. &#xD;
Remove redundant relationships, try to make relationships unidirectional, and &#xD;
so forth. See &lt;a class=&quot;elementLinkWithType&quot; href=&quot;./../../../openup/guidances/guidelines/analyze_the_design_4C4750C0.html&quot; guid=&quot;__MnggPTdEduDKIuqTXQ8SA&quot;>Guideline: Analyze the Design&lt;/a> for more information. &#xD;
&lt;h3> Refine the design &lt;/h3>&#xD;
&lt;p> After creating an implementation that includes a set of collaborating elements, &#xD;
with the behavior and relationships robust enough to pass developer tests, the &#xD;
design can be improved and transformed into a more robust and maintainable system. &#xD;
&lt;/p>&#xD;
&lt;p> The visibility of each operation should be selected to be as restrictive as &#xD;
possible. Based on walking through the scenario, it should be clear which operations &#xD;
must be available to other elements in the design and which can be considered &#xD;
behavior inside of the element that has the operation. Minimizing the number &#xD;
of public operations creates a more maintainable and understandable design. &#xD;
&lt;/p>&#xD;
&lt;p> With respect to parameters, the return value, and a description of how it &#xD;
perform the behavior, operations can be detailed at a lower level that drives &#xD;
the actual implementation, or that detail might be left to be handled when writing &#xD;
the code. &lt;/p>&#xD;
&lt;p> Data attributes can be identified based on information needed to support behavior &#xD;
or based on additional requirements, such as information to be presented to &#xD;
the user or transmitted to another system. Avoid indiscriminate domain analysis, &#xD;
because there might be a great deal of data in the domain that is not needed &#xD;
to support the requirements. Data attributes can simply be identified or they &#xD;
can be designed in detail, with attribute types, initial values, and constraints. &#xD;
Decide on the visibility of the data attribute; operations to access and update &#xD;
the data can be added or deferred until implementation. &lt;/p>&#xD;
&lt;p> Generalization and interfaces can be applied to simplify or otherwise improve &#xD;
the design. Ensure that the use of these techniques actually improves the design, &#xD;
rather than bogging it down with complexity. For example, common behavior can &#xD;
be factored into a parent class through generalization or out to a helper class &#xD;
through delegation. The latter solution can be more understandable and maintainable, &#xD;
because generalization is an inflexible relationship (see the section that follows &#xD;
on inheritance). &lt;/p>&#xD;
&lt;p> The refinement of any portion of the design could include another pass through &#xD;
the design process. You might find that what was initially identified as a single &#xD;
behavior of an element warrants a detailed walkthrough of the collaborating &#xD;
elements to realize that behavior. &lt;/p>&#xD;
&lt;p> When updating an existing design -- especially one that has had portions already &#xD;
implemented -- apply &lt;a class=&quot;elementLink&quot; href=&quot;./../../../openup/guidances/guidelines/refactoring_33F165CA.html&quot; guid=&quot;_OlyWoOX7Edu8VZPtlaU33g&quot;>Refactoring&lt;/a> &#xD;
to ensure that the improved design continues to perform as expected. &lt;/p>&#xD;
&lt;h4> Organize elements &lt;/h4>&#xD;
&lt;p> In a design of any notable size, the elements must be organized into packages. &#xD;
Assign the elements to existing or new packages, and ensure that the visibility &#xD;
relationships between the packages support the navigation required between the &#xD;
elements. Decide whether each element should be visible to elements outside &#xD;
of the package. &lt;/p>&#xD;
&lt;p> When structuring the design into packages, consider &lt;a class=&quot;elementLink&quot; href=&quot;./../../../openup/guidances/guidelines/layering_F169CF07.html&quot; guid=&quot;_0gpkAMlgEdmt3adZL5Dmdw&quot;>Layering&lt;/a> &#xD;
and other patterns. Although all design work must conform to existing architectural &#xD;
decisions, the allocation of elements to packages and possible updates to package &#xD;
visibility are of significant architectural concern. The developer should collaborate &#xD;
with the architect to ensure that package-level decisions are in accordance &#xD;
with the rest of the architecture. &lt;/p>&#xD;
&lt;p> This guideline first talks about the identification and design of the elements &#xD;
and then about organizing the elements into packages. However, this is not a &#xD;
strict order of events. There is nothing wrong with identifying a package structure &#xD;
for the system and then populating that structure with identified elements, &#xD;
as long as the actual elements identified are allowed to influence the resulting &#xD;
package structure. See the sections on identification and behavior of elements &#xD;
in &lt;a class=&quot;elementLinkWithType&quot; href=&quot;./../../../openup/guidances/guidelines/analyze_the_design_4C4750C0.html&quot; guid=&quot;__MnggPTdEduDKIuqTXQ8SA&quot;>Guideline: Analyze the Design&lt;/a>. &lt;/p>&#xD;
&lt;h4> Identify patterns &lt;/h4>&#xD;
&lt;p> Identifying &lt;a class=&quot;elementLink&quot; href=&quot;./../../../openup/guidances/concepts/pattern_10BE6D96.html&quot; guid=&quot;_0YJvUMlgEdmt3adZL5Dmdw&quot;>Pattern&lt;/a>s &#xD;
and seeking opportunities to leverage patterns are useful techniques. The value &#xD;
of patterns here is that they provide a shortcut to a robust design. For instance, &#xD;
when there's an interface realized by multiple classes, it’s possible that an &#xD;
Abstract Factory pattern will be useful, because the pattern encapsulates the &#xD;
logic of what class should be instantiated. The more experienced a developer &#xD;
is, the better the developer is at identifying opportunities to take advantage &#xD;
of, or leverage, patterns. &lt;/p>&#xD;
&lt;p> The longer you use patterns, the easier it will be to identify opportunities &#xD;
to leverage them. At first, look for places where you can clearly specify the &#xD;
need for some behavior. Perhaps there's a place where some function or algorithm &#xD;
must be shared between many different classes. How can this behavior be shared &#xD;
over and over among heterogeneous classes? Or perhaps a third-party library &#xD;
is replacing a block of custom code. Is there a way to make this transition &#xD;
easier by creating an interface that can use either implementation? These are &#xD;
opportunities for finding or possibly creating a pattern. &lt;/p>&#xD;
&lt;p>&#xD;
See also &lt;a class=&quot;elementLinkWithUserText&quot; href=&quot;./../../../openup/guidances/supportingmaterials/references_6CCF393.html#GAM95&quot; guid=&quot;_9ToeIB83Edqsvps02rpOOg&quot;>[GAM95]&lt;/a>&amp;nbsp;and &lt;a class=&quot;elementLinkWithUserText&quot; href=&quot;./../../../openup/guidances/supportingmaterials/references_6CCF393.html#SHA05&quot; guid=&quot;_9ToeIB83Edqsvps02rpOOg&quot;>[SHA05]&lt;/a>&#xD;
&lt;/p>&#xD;
&lt;h3> Inheriting behavior versus inheriting interfaces &lt;/h3>&#xD;
&lt;p> Inheritance (or generalization) is often used as a shortcut during implementation &#xD;
to quickly re-use behavior (code).&lt;/p>&#xD;
&lt;p>&lt;b>Caution: &lt;/b>&lt;br />&#xD;
Work hard to remove behavior inheritance in design. It will almost always cost &#xD;
more effort than it saves. &lt;/p>&#xD;
&lt;p> Inheritance is a very rigid structure with strict rules. A class that inherits &#xD;
from another class is establishing an&lt;b> is-a&lt;/b> relationship. The inheriting &#xD;
class is a type of the parent class-- the child has the same relationships and &#xD;
behaviors as the parent. In most hierarchies, it will be impossible to maintain &#xD;
this type of relationship. Exceptions quickly creep in, and it’s common to find &#xD;
child classes that remove or override behavior in the parent classes. This increases &#xD;
maintenance costs and makes it difficult to understand what each class does. &#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
It’s also too tempting to instantiate parent classes, which makes the parent class both abstract and concrete. If a&#xD;
class has children, it must be abstract enough to support the generalized behavior of the children. But if it’s&#xD;
instantiated, it must be concrete enough to provide specific behavior. It’s rarely possible to fulfill both of these&#xD;
competing imperatives at the same time, and the design suffers.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
Use association and aggregation relationships instead of inheriting behavior. Patterns are a good tool to leverage in&#xD;
breaking up inheritance hierarchies.&#xD;
&lt;/p>&#xD;
&lt;p> Inheriting interfaces is safe, because only the description and not the implementation &#xD;
of what needs to be done is reused. &lt;/p>&#xD;
&lt;p>&#xD;
Avoiding inheriting behavior is an application of the Open-Closed Principle. See &lt;a class=&quot;elementLinkWithType&quot; href=&quot;./../../../openup/guidances/concepts/design_E36137FA.html&quot; guid=&quot;_bFjlAPTYEduDKIuqTXQ8SA&quot;>Concept: Design&lt;/a> for&#xD;
more information.&#xD;
&lt;/p>&#xD;
&lt;h3> &lt;strong>Revisit the analysis&lt;/strong> &lt;/h3>&#xD;
&lt;p> The &lt;a class=&quot;elementLinkWithType&quot; href=&quot;./../../../openup/guidances/guidelines/analyze_the_design_4C4750C0.html&quot; guid=&quot;__MnggPTdEduDKIuqTXQ8SA&quot;>Guideline: Analyze the Design&lt;/a>&amp;nbsp;describes techniques that are also useful when evolving &#xD;
a more robust design.&lt;br />&#xD;
&lt;/p>&#xD;
&lt;h4> &lt;strong>Consider the architecture&lt;/strong> &lt;/h4>&#xD;
&lt;p> The architecture must be considered in all design changes. The “best” design &#xD;
for a particular part of the solution may not be appropriate because of architectural &#xD;
constraints that must support the entire system. The architecture may also help &#xD;
to make design decisions, because it can be part of the selection criteria between &#xD;
two potential solutions. Developers should always be up-to-date with the architecture &#xD;
and review it often, particularly in early iterations. &lt;/p>&#xD;
&lt;p> This guideline remarks on conforming to the architecture in various ways; &#xD;
it is written as though it is about designing within a pre-existing architecture. &#xD;
Although projects will often have pre-existing architectures available, a particular &#xD;
architecture is the result of design activities. Therefore, in addition to discussing &#xD;
conformance to some existing architecture, you must also consider the creation &#xD;
of the architecture, as well as updates and improvements based on the work of &#xD;
design. &lt;/p>&#xD;
&lt;p> Also, see&amp;nbsp;&lt;a class=&quot;elementLinkWithUserText&quot; href=&quot;./../../../openup/guidances/supportingmaterials/references_6CCF393.html#SHA05&quot; guid=&quot;_9ToeIB83Edqsvps02rpOOg&quot;>[SHA05]&lt;/a> &#xD;
for a&amp;nbsp;useful introduction to object-oriented techniques that should be &#xD;
applied when evolving a good design. &lt;/p></mainDescription>
</org.eclipse.epf.uma:ContentDescription>