blob: ca228122c9abfd01b3866cc4b86e3521bff17754 [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.6/uma.ecore" xmlns:epf="http://www.eclipse.org/epf" epf:version="1.5.1" xmlns:rmc="http://www.ibm.com/rmc" rmc:version="7.5.1" xmi:id="-Vp61zQMUoP-Icm5jgDar7A" name="new_guideline,_vO2uoO0OEduUpsu85bVhiQ" guid="-Vp61zQMUoP-Icm5jgDar7A" changeDate="2008-02-15T05:30:27.000-0800" version="1.0.0">
<mainDescription>&lt;p>&#xD;
Maximizing reuse has always been an important goal of software development. It's better to re-use than to expend the&#xD;
cost of creating something new, testing it, and releasing it for the first time with the risk of hidden problems that&#xD;
all new software has. Languages, particularly object-oriented ones, have been developed to make reuse easier. But a&#xD;
language alone isn't enough to provide cost effective reuse. The bulk of reusable software comes from skilled&#xD;
developers and architects who are able to identify and leverage reuse opportunities.&#xD;
&lt;/p>&#xD;
&lt;h3>&#xD;
What is a Reusable Asset?&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
The following are some examples of reusable software assets:&#xD;
&lt;/p>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
Architectural frameworks&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Architectural mechanisms&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Architectural decisions&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Constraints&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Applications&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Components&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
COTS software&amp;nbsp;&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;h3>&#xD;
Identifying Reuse Opportunities&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
There are three perspectives to look at when reusing software: code (implementation), design, and framework or&#xD;
architecture.&amp;nbsp; Architects should look to reuse significant application frameworks such as layers that can be&#xD;
applied to many different types of applications (for more information, see &lt;a class=&quot;elementLinkWithType&quot;&#xD;
href=&quot;./../../../core.tech.common.extend_supp/guidances/guidelines/layering_F169CF07.html&quot;&#xD;
guid=&quot;_0gpkAMlgEdmt3adZL5Dmdw&quot;>Guideline: Layering&lt;/a>. Developers should look to designs and &lt;a class=&quot;elementLink&quot;&#xD;
href=&quot;./../../../core.tech.common.extend_supp/guidances/concepts/pattern_10BE6D96.html&quot;&#xD;
guid=&quot;_0YJvUMlgEdmt3adZL5Dmdw&quot;>Pattern&lt;/a>s that can be reused to produce desired behavior or robust structures. They&#xD;
should also look at how to reduce the amount of code that needs to be written by leveraging stable components and code&#xD;
that has been proven in production environments.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
The best way to enable a team to find opportunities for reuse is to exercise excellent design and coding practices.&#xD;
It's difficult to find code and design that can be reused when dealing with large classes, classes that don't have a&#xD;
clearly defined focus, or classes with relationships that are difficult to understand. Classes should be small, easy to&#xD;
understand, and highly cohesive to make it easier to identify reuse opportunities. Any functionality that can be&#xD;
reasonably separated into another class should be. Another way of saying this is that any concept that could be applied&#xD;
to more than one type of class should be its own class.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
For example, if some calculations are added to an existing class, it may make sense to then refactor those calculations&#xD;
into a new helper class. Those calculations can&amp;nbsp;then be re-used in any number of other classes without the burden&#xD;
of having to know about the functionality of the original class.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
The simplest but least efficient way to identify reuse opportunities is to &quot;smell&quot; similar code. A developer may recall&#xD;
doing something similar to what they're designing or implementing now. Once the previous implementation has been&#xD;
discovered or recalled it can be reused. Developers will always find reuse opportunities this way. But the unstructured&#xD;
nature of it won't maximize the potential areas for reuse.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
Collaboration is a good technique for identifying reuse opportunities. It provides a structure where identifying reuse&#xD;
- instead of writing code - is the goal of the exercise. And the more brains that are looking for reuse opportunities,&#xD;
the more likely it is that they'll be found. A brainstorming or review meeting that focuses on identifying reuse&#xD;
opportunities would be useful to support this.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
Patterns are good ways to find reuse opportunities in designs and frameworks. See &lt;a class=&quot;elementLinkWithType&quot;&#xD;
href=&quot;./../../../core.tech.common.extend_supp/guidances/concepts/pattern_10BE6D96.html&quot;&#xD;
guid=&quot;_0YJvUMlgEdmt3adZL5Dmdw&quot;>Concept: Pattern&lt;/a>&amp;nbsp;for more information.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
Analyzing behavior is another good way to identify potential areas for reuse. Analyze how classes need to collaborate&#xD;
in order to deliver some specific functionality such as a requirement or feature. This collaboration can be documented&#xD;
in sequence (behavior) and class (structure) diagrams and can be reused in similar circumstances.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
After looking for similar behavior and returned values, then look for similarity of parameters. If their&#xD;
interfaces&amp;nbsp;are not an exact match for the component interfaces being proposed, you can modify the&#xD;
proposed&amp;nbsp;signatures to increase the degree of reuse. Some design mechanisms, such as performance or security&#xD;
requirements, may disqualify a component from reuse even when there is&amp;nbsp;a perfect match between operation&#xD;
signatures.&#xD;
&lt;/p>&#xD;
&lt;p align=&quot;left&quot;>&#xD;
A common set of components may exist that provides many of the &lt;a class=&quot;elementLink&quot;&#xD;
href=&quot;./../../../core.tech.common.extend_supp/guidances/concepts/arch_mechanism_2932DFB6.html&quot;&#xD;
guid=&quot;_mzxI0A4LEduibvKwrGxWxA&quot;>Architectural Mechanism&lt;/a> that you need&amp;nbsp;for the new system. These components may&#xD;
be available either because they were developed or purchased previously for&amp;nbsp;similar systems. Given their&#xD;
suitability and compatibility within the software architecture, there may be a need to reverse-engineer these&#xD;
components to represent them in a design model and reuse them in a project.&#xD;
&lt;/p>&#xD;
&lt;p align=&quot;left&quot;>&#xD;
Similar thinking applies to&amp;nbsp;existing databases. Part of the information to be used by the application under&#xD;
development may already reside in a database. You may be able to get the classes that represent the database structures&#xD;
that hold this information by reverse-engineering the database.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
&lt;a class=&quot;elementLink&quot; href=&quot;./../../../core.tech.common.extend_supp/guidances/concepts/refactoring_1B63BA3B.html&quot;&#xD;
guid=&quot;_Poc7IPDzEdqYgerqi84oCA&quot;>Refactoring&lt;/a> should always be considered when reusing code. Code (or design) is often&#xD;
not originally written for re-use, or reusable code may not be a perfect fit for a new situation.&#xD;
&lt;/p>&#xD;
&lt;h3>&#xD;
Assessing and Selecting Assets to Reuse&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
To assess and select assets to reuse on your project, you need to understand the requirements of the system's&#xD;
environment. You also need to understand the scope and general functionality of the system that the stakeholders&#xD;
require. There are several types of assets to consider, including (but not limited to): reference architectures;&#xD;
frameworks; patterns; analysis mechanisms; classes; and experience. You can search asset&amp;nbsp;repositories (internal or&#xD;
external to your organization) and industry literature to identify assets or similar projects.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
You need to assess whether available assets contribute to solving the key challenges of the current project and whether&#xD;
they are compatible with the project's architectural constraints. You also need to analyze the extent of the fit&#xD;
between assets and requirements, considering whether any of the requirements are negotiable (to enable use of the&#xD;
asset). Also, assess whether the asset could be modified or extended to satisfy requirements, as well as what the&#xD;
tradeoffs in adopting it are, in terms of cost, risk, and functionality.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
Leverage reuse of existing components by evaluating their interfaces and the behavior that they provide. Reuse&#xD;
components when their interfaces are similar or match the interfaces of components you would need to develop from&#xD;
scratch. If not similar, modify the newly identified interfaces so you improve the fit with existing components&#xD;
interfaces. Work with developers to gain consensus on the suitability of using existing components.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
Finally, decide, in principle, whether to use one or more assets, and record the rationale for this decision.&#xD;
&lt;/p>&#xD;
&lt;h3>&#xD;
Reuse Techniques&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
Reuse can be performed differently depending on the capabilities of the implementation environment. The simplest&#xD;
technique is to copy the code from one place to another. This isn't advisable because it's not really reuse. Multiple&#xD;
copies of source code are difficult to maintain and can eventually diverge from each other. Reuse is about using the&#xD;
same code to perform similar tasks as a way to increase quality and reduce overhead.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
Some languages, such as C++, support templates. Templates, sometimes referred to as parameterized code, are a precursor&#xD;
to patterns. Templates are code with parameters that are applied just when the code's needed, at compile time. The C++&#xD;
Standard Template Library (STL) is one example. It provides many types of reusable containers (lists, sets, safe&#xD;
arrays, etc) that don't have some of the drawbacks of inheritance. Templates such as these are also useful as mix-in&#xD;
classes in languages like C++ that support multiple inheritance. Because mix-ins are implemented as templates, they&#xD;
allow for a type of multiple inheritance without the baggage.&#xD;
&lt;/p>&#xD;
&lt;h3>&#xD;
Inheritance and Aggregation&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
Inheritance (also known as generalization) is an easy way to implement polymorphism and has been used as the primary&#xD;
mechanism for reuse in modern object-oriented languages. This is unfortunate, as inheritance imposes a rigid structure&#xD;
on the software's design that is difficult to change. Any inheritance hierarchy that shares code from parents to&#xD;
children will have problems when it grows to be three or more levels deep. Too many exceptions occur to maintain a pure&#xD;
&quot;is-a&quot; relationship between parents and children, where children are always considered to have all the properties and&#xD;
behaviors of the parents. Inheritance should be used to share definitions (interfaces), not implementations. Years of&#xD;
difficulties with inheriting implementations have made this practice a primary object-oriented design principle.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
Whenever inheritance is used, it is best to have only the last child class (leaf node) of the inheritance hierarchy be&#xD;
instantiated. All parent classes should be abstract. This is because a class that tries to be both reusable and&#xD;
concrete - to provide reusable and specific behavior at the same time - almost always fails to fulfill either goal.&#xD;
This is a dimension of cohesiveness. One thing that makes a class cohesive is that it's dedicated to reuse or dedicated&#xD;
to a specific implementation, but not both.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
Aggregation is a technique that collects or aggregates functionality into larger elements of functionality. It provides&#xD;
a structure that's far more flexible and reusable than inheritance. It's better to reuse implementation and design by&#xD;
aggregating small pieces of functionality together rather than trying to inherit the functionality from a parent.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
You may also find reuse opportunities by reviewing interfaces. If interfaces describe similar behavior it may be&#xD;
possible to eliminate one of the interfaces, have just one implementation realize both interfaces, or refactor the&#xD;
interfaces to put redundant content in a new, simpler interface.&#xD;
&lt;/p>&#xD;
&lt;h3>&#xD;
Finding Reusable Code&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
There are many sources of reusable code beyond what the developers are writing for a specific project. Other places&#xD;
from which to harvest code include the following:&#xD;
&lt;/p>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
Internal (corporate) code libraries&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Third party libraries&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Built-in language libraries&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Code samples from tutorials, examples, books, etc.&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Local code guru or knowledgeable colleague&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Existing system code&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
Open source products (be sure to follow any licensing agreements)&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;p>&#xD;
Also, many tools that generate code will generate comprehensive code based on minimal specification. For example, a&#xD;
design tool might generate the member variable plus a get and a set operation when the designer specifies an attribute.&#xD;
Other more sophisticated tools with knowledge of a specific framework can generate voluminous code to ensure that a&#xD;
class conforms to the framework. An example of this would be a tool that generates significant additional code when a&#xD;
class is marked as a Java entity bean. This sort of consistent transformation from a specification (the design) to an&#xD;
implementation (the code) could be considered a form of code reuse as well.&#xD;
&lt;/p>&#xD;
&lt;h3>&#xD;
Don't Reuse Everything&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
Reuse makes code and design cheap to use but expensive to build. It requires experience and thoughtful consideration to&#xD;
create an implementation or design that's abstract enough for others to re-use, but concrete enough to be truly useful.&#xD;
Reusable code must also be maintained. Many organizations have difficulty assigning responsibility for maintaining&#xD;
reusable code if they don't have a group dedicated to reuse.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
It's usually not a good idea to create code or designs for reuse unless you know it's going to be reused. It's better&#xD;
to refactor software to be more reusable after it's discovered that they can be reused. One rule of thumb is to write&#xD;
for reuse only when you know you'll use it at least 3 times. Otherwise the cost of building and maintaining that part&#xD;
of the software will not be recovered by reduced overhead in other areas of development.&#xD;
&lt;/p></mainDescription>
</org.eclipse.epf.uma:ContentDescription>