blob: 4e3471e3457223cb51670291cacce7dfad0da722 [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="-Vp61zQMUoP-Icm5jgDar7A"
name="new_guideline,_vO2uoO0OEduUpsu85bVhiQ" guid="-Vp61zQMUoP-Icm5jgDar7A" changeDate="2007-06-22T11:27:37.516-0700"
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 existing code and&#xD;
design than to expend the cost of creating something new, testing it, and releasing it for the first time with the risk&#xD;
of hidden problems that all new software has. Languages, particularly object-oriented ones, have been developed to make&#xD;
reuse easier. But a language alone isn't enough to provide cost effective reuse. The bulk of reusable software comes&#xD;
from skilled developers and architects who are able to identify and leverage reuse opportunities.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
There are three perspectives to look at when reusing software: code (implementation), design, and framework or&#xD;
architecture. Architects should look to reuse significant application frameworks such as layers that can be applied to&#xD;
many different types of applications. Developers should look to designs and patterns that can be reused to produce&#xD;
desired behavior or robust structures. They should also look at how to reduce the amount of code that needs to be&#xD;
written by leveraging stable components and code that has been proven in production environments.&#xD;
&lt;/p>&#xD;
&lt;h4>&#xD;
Identifying Reuse Opportunities&#xD;
&lt;/h4>&#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; href=&quot;./../../../openup/guidances/concepts/pattern_10BE6D96.html&quot; 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;
&lt;a class=&quot;elementLink&quot; href=&quot;./../../../openup/guidances/concepts/refactoring_1B63BA3B.html&quot; 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;h4>&#xD;
Reuse Techniques&#xD;
&lt;/h4>&#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;h4>&#xD;
Inheritance and Aggregation&#xD;
&lt;/h4>&#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;h4>&#xD;
Finding Reusable Code&#xD;
&lt;/h4>&#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;h4>&#xD;
Don't Reuse Everything&#xD;
&lt;/h4>&#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>