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