CSC/ECE 517 Fall 2009/wiki2 7 cn: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
 
 
(59 intermediate revisions by 2 users not shown)
Line 1: Line 1:
='''Problem Statement'''=
='''Problem Statement'''=
Different languages have different mechanisms for "code reuse."  Assembly and low level languages have macros, C/C++ has includes, Ruby has mixins and modules, Java has packages, and there are many other concepts around reuse and extension. Here is a page that describes the various mechanisms, groups the mechanisms into logical categories, and discusses the advantages and disadvantages of the various schemes, in terms of simplicity, performance, reliability, or other factors.


The list of refactorings has become quite long & people don't remember long lists very well.  To promote learning the different patterns, they should be categorized in some way, or perhaps, along various dimensions.Here is an attempt to categorize the various available refactoring methods into different categories along as many different dimensions as makes sense. As a reference we have taken the list of refactorings methods available at http://www.refactoring.com/catalog/index.html.
='''Code Reuse - A Brief Overview'''=
Code reuse, also called software reuse, is the use of existing software, or software knowledge, to build new software. Code reuse in software development is something assumed literally through re-using bits of code in more than one place. It is truly achieved through using common libraries and interfaces accessible to both the entire application and to other applications in the domain. Here are some of the features of code reuse.  


='''Categorization of Refactoring Methods'''=
=='''Reuse is not duplication'''==
=='''Categorization Framework Used'''==
Duplicating code is the result of a copy-paste scenario. The moment you have copy-pasted a module of code to two locations in your application you’ve just created an additional maintenance point. Also if you have coded a bug into the original code & duplicated it in multiple locations, the bug has now been instantiated in more than one place. Reuse is different from duplication. In code reuse the logic or work that a module does in multiple areas of the application can be reused from one place.The code doesn’t have to physically reside in all of those places to get reused.
When an application is developed using an object oriented programming language the code architecture is designed in the following way. First the functionality of the application is divided into major chunks and assigned to sets of packages which form the first level of hierarchy for the program.  


The second level of hierarchy is the compilation unit which has access to all public types declared in its package and also automatically imports them. Types consist of classes and interfaces.  
=='''Interfaces'''==
Reuse is not always functional code that needs to be applied in more than one place. It can be obtained through the use of interfaces and generics as well. By using a solid interface design to allow any type of object with a compatible set of methods to be used in a piece of your application, you allow for everything on both sides of that interface to be easily interchangeable. Other type of interface-like methods that promote architectural reuse are generics, tag libraries, and dozens of frameworks out there that allow pieces to be easily decoupled and injected into the application.


The functionality implemented in a package is further broken down and implemented using classes at the third level of hierarchy. Classes are made out of items, which are basically methods and fields. Fields declare data which are associated with the class.Interfaces encode the similarities among classes.  
=='''Advantages of Code Reuse'''==
* Reusing code saves programming time, which reduces costs.
* Sharing code can help prevent bugs by reducing the amount of code that needs to be written to perform a task. The shared code can also be tested separately from the end applications.
* Separating code into common libraries lets programmers specialize in their particular strengths. A security library, for example, can be built by security experts while a user interface which uses the library can let UI experts focus on their tasks.
* Delegation of tasks into shared modules allows offloading of some functionality onto separate systems.


The fourth level of hierarchy consists of objects which act as data structures and store data associated with the class. This helps to store multiple values of the same type of data.
=='''Drawbacks'''==


At the lowest level i.e the fifth is the data, which is a part of the object. At this level, the code which is a part of the method processes this data.  
* Maintenance nightmare – If for any reason one to make changes in the copied section, changes have to be made ALL the copies.
* Unorganized – Reused code tends to be unorganized .It may generate create massive amounts of code which is difficult to decipher after a while.


This hierarchy is followed during any application development using an object oriented language and when an analyst is asked to refactor code, he/she also parses through this same hierarchy to understand the code functionality and to find spots where the code can be refactored.  
=='''Examples of Effective Code Reuse'''==
* Google Chrome is an excellent example of code reuse, it uses at least 25 different software Libraries.
* Matlab programs are also a good example of code reuse where one reuses different functions from the matlab tool box.


Most of the refactoring methods belong to level 3, level 4 and level 5, hence these categories have again been divided into sub-categories, to reduce generalization & make the categorization more specific. Here is an attempt to make categorization of the refactoring methods based on the said hierarchy. Also there are a few categories which aren't derived from the above hierarchy. Here are the categories and sub-categories using which the refactoring methods available at http://www.refactoring.com/catalog/index.html have been categorized.
='''General Methods for Code Reuse in Object Oriented Languages'''=


=='''Categories'''==
The types of Code Reuse used for the Object Oriented Framework are as follows:
===Refactoring the Package===
A refactoring method will fall under this category if the changes made affect the package structure or add to the functionality to the package. The refactoring method generally may involve breaking a package to smaller packages to divide the functionality or moving classes to a more relevant package.
*Extract Package
*Move Class


===Refactoring the Class===
* Architected Reuse: The identification, development, and support of large-scale, reusable assets via enterprise architecture.    Your enterprise architecture may define reusable domain components, collections of related domain/business classes that work  together to support a cohesive set of responsibilities, or service domains which bundle a cohesive collection of services together. 
* Pattern Reuse: The use of documented approaches to solving common problems within a specified context.  With pattern reuse you’re not reusing code, instead you are reusing the thinking that goes behind the code.  Patterns can be a multiple levels such as analysis, design, and architecture are the most common. 
* Framework Reuse: The use of collections of classes that together implement the basic functionality of a common technical or business domain.Horizontal frameworks, such as a security framework or user interface framework such as the Java Foundation Class (JFC) library and vertical frameworks, such as a financial services framework, are common.
* Artifact Reuse: The use of previously created development artifacts such as use of cases, standards documents, domain-specific models, procedures and guidelines, and even other applications such as a commercial off the shelf (COTS) package to give one a kick start on a new project. 
* Module Reuse.  The use of pre-built, fully encapsulated "modules", components, services, or code libraries in the development of an application. A module is self sufficient and encapsulates only one concept.  Module reuse differs from code reuse as one don’t to have access to the source code.
* Template Reuse. The practice of using a common set of layouts for key development artifacts such as documents, models, and source code within an organization. 
* Code Reuse. The reuse of source code within sections of an application and potentially across multiple applications.  At its best code reuse is accomplished through the sharing of common classes and/or collections of functions and procedures.  At its worst code reuse is accomplished by copying and then modifying existing code causing a maintenance nightmare.


*'''Changing Class Association'''
The Page now talks about reuse in different languages such as C, C++, Java & Ruby.
A refactoring method falls in this category if it tries to change the association between two classes so that features of a class may be added or removed.
*Change Unidirectional Association to Bidirectional
*Change Bidirectional  Association to Unidirectional
*Extract Interface


*'''Change of Class Structure''' A refactoring method falls in this category when it tries to change the hierarchy that the classes share amongst them.
='''Code Reuse in C/C++'''=
**Splitting of Class
 
  *Duplicate Observed Data
=='''Functions'''==
  *Extract Class
(Applicable for both C/C++)
  *Extract SubClass
 
  *Extract SuperClass
Instead of writing a same function multiple times, we can call the function, thus making the code more concise, readable & modular. Another way of using functions is to write them in header files & then including the header files in the code. Later the functions written in the Header File can be called directly from the main program.
  *Separate Data Access Code
 
  *Localize Disparate Logic
Different Types of Header Files used in C/C++ are as follows:
   
* assert.h, math.h, string.h, stdio.h, time.h etc
**Merging of Class
 
  *Collapse Hierarchy
Simple Program to Illustrate C Functions:
  *Replace Subclass with Fields
 
  *Inline Class
''#''include <stdio.h>
void print_message(void);
{
printf("Hello World \n");
}
 
Main Program
int main(void)
{
print_message();
return 0;
}
 
=='''Classes'''==
(Applicable only for C++, Java)
 
Classes define methods which process the data present in multiple objects. Thus the same method code gets re-used for all the objects of the class, thus providing code re-use. C++ also defines other features for classes which promote code reuse. Eg: Funtion overloading helps the same function to perform different operations based on the parameters passed to it, thus allowing the use of one function to do multiple tasks.
 
An simple example of an class is as follows:-
// classes example
''#''include <iostream>
using namespace std;
class CRectangle {
  int x, y;
public:
  void set_values (int,int);
  void set_values (int);
  int area (int x) {return (x*x);}
  int area (int x, int y) {return (x*y);}
  };
 
void CRectangle::set_values (int a, int b) {
x = a;
y = b;
}
void CRectangle::set_values (int a) {
x = a;
}
 
  int main () {
  CRectangle rect;
  rect.set_values (5,4);
  cout << "area: " << rect.area();  //Output = 20
  rect.set_values (3,4);
  cout << "area: " << rect.area();  //Output = 12
  CRectangle sqr;
  sqr.set_values (7);
  cout << "area: " << sqr.area(); //Output = 49 : Example of Function Overloading & Classes.
  return 0;
  }
 
=='''Inheritence'''==
(Applicable for C++, Java)
 
Derived Classes can reuse code from super class hierarchy. Variables and methods from the super class get added to the derived class, thus preventing duplication of code & enabling code re-use. The derived class can also have some extra methods/variables added to it if required. C++ also supports multiple inheritance where a base class extends more than one class.


*'''Inter-Class Movement of Items'''
class exforsys
A refactoring method falls in this category when it tries to move functionality/detail between classes. This may involve movement of constructors, fields or methods between classes.
  {
  *Pull up Constructor Body
  public:
  *Pull up Field
  exforsys(void) { x=0; }
  *Pull up Method
  void f(int n1)
*Push Down Field
  {
*Push Down Method
  x= n1*5;
  *Move Field
  }
*Move Method
  void output(void) { cout<<x; }
   
  private: int x;
*'''Moving Additional Functionality to Client Class'''
  };
A refactoring method falls in this category when functionality needs to be added to a server class which cannot be altered. The refactoring method achieves it by adding sever class extensions to the client method.
  *Introduce Local Extension 
*Introduce Foreign Method


*'''Replacement of Class Instantiation with Constructors'''
class sample: public exforsys
A refactoring method falls in this category when it tries to convert loading of some of the classes from dynamic to static or vice-versa.
  {
public:
sample(void) { s1=0; }
void f1(int n1)
  {
s1=n1*10;
  }
void output(void)
  {
exforsys::output();
cout << s1;
  }
private: int s1;
  };


  *Convert Static to Dynamic Construction
  int main(void)
  *Convert Dynamic to Static Construction
  {
sample s;
s.f(10);
s.output();
  s.f1(20);
s.output();
  }


===Refactoring the Method===
=='''Libraries'''==
(Aplicable for C++ only)


*'''Meaningful and Detailed Method Calls'''
Standard C++ Libraries are a collection of functions, constants, classes, objects & templates which extend the C++ language providing basic functionality to perform several tasks. Eg: Classes to interact with OS, Data containers, Iterators to operate them & algorithms commonly needed.
A refactoring method will fall under this category if it modifies a method call to pass more data to the method or tries to make the method call more understandable.
*Add Parameter
*Preserve Whole Object
*Rename Method


*'''Change of Structure of the Method Code'''
Some of the few C++ Standard Template Libraries(STL) are as as follows:
A refactoring method will fall under this category if it deliberately changes the internal flow of the code without affecting the output. These methods need not result in the optimization of the code or simplification.
* Containers Library eg: Bitset, Deqeue, List, Map, Queue, Vector.
*Consolidate Conditional Expression
* Iterators Library eg: Iterator
*Encapsulation Collection
*Extract Method
*Inline Method
*Form Template Method
*Replace Nested Conditional with Guard Clauses
*Replace Parameter with Method


*'''Change Method Call Hierarchy/Sequence'''
='''Code Reuse in Java'''=
A refactoring method will fall in this category when it tries to change the method call flow in any way.  
Some of the code reuse techniques such as Classes, Function Overloading & Inheritance are common for the Java Programming Language as well. Though there will some differences such as: Java doesn't support multiple inheritance like C++. Java makes use of Interfaces & Abstract Classes to achieve Multiple Inheritance.
*Remove Middle man
*Replace Delegation with Inheritance
*Replace Inheritance with Delegation


*'''Improve Method Readability'''
=='''Re-using Java Classes'''==
A refactoring method will fall under this category when it increases the readability of the code for a new person reading the code or for debugging purpose if ever needed.
The code for a class can now be reused in other class by making use of the new method. Here is an example of the same:
*Introduce Explaining Variable
*Replace Magic No with Symbolic Constant
*Replace Recursion with Iteration
*Split Temporary Variable


*'''Method Code Refactoring based on Method Arguments'''
public class helloworld_use {
A refactoring method will fall under this category when it makes the behavior of the executed method code, change depending on the argument passed, or when it frees the method code of this feature.
public static void main(String args[]) {
  *Parameterize Method
  helloworld myhello = new helloworld();
  *Replace Conditional with Polymorphism
  myhello.greeting_text = "Hello again";
  *Replace Conditional with Visitor
System.out.println(myhello.greeting());
  *Replace Parameter with Explicit Methods
  }
  }


===Refactoring the Object===
The code can be compiled and run:
javac helloworld_use.java
java helloworld_use


*'''Replacements with Objects'''
The end result is the words "Hello again" written to the screen, but the key thing here is that the new application requires no new code to be written for that to happen.
A refactory method will fall under this category when the code is changed such that its execution is more centered around the object. And different parameters like array, data values are replaced by objects.
*Introduce Null Object
*Introduce Parameter Object
*Replace Array with Object
*Replace Data Value with Object
*Replace Method with Method Object
*Replace Record with Data Class


*'''Object Initialization'''
=='''Inheritance and Interfaces'''==
A refactory method will fall under this category when it tries to alter the constructor used for the initialization of the object.
*Replace Constructor with Factory Method
*Remove Setting Method


*'''Accessing the Object/Data'''
Interfaces are a definition which decide the methods that need to be declared/used in a class. Interfaces are essential to the Java language. They provide for multiple inheritance as well as information hiding and code re-use. Interfaces have advantages over classes because of improved information hiding and code re-use. A very clean design might use interfaces instead of base classes.Inheritance & Interfaces can be used together to implement code reuse.Here is an generic example of an interfaces.  
A refactory method will fall under this category if the method changes the way an object or data is accessed.
*Change Reference to Value
*Change Value to Reference
*Refactor Architecture by Tiers
*Self Encapsulate Field


===Refactoring the Code===


*'''Code Optimization'''
interface MinMax<T extends Comparable<T>> {
A refactoring method will fall under this category when the method brings about change in the code such a way that its execution is optimized.
  T min();
  *Consolidate Duplicate Conditional Fragments
  T max();
  *Eliminate Inter-Entity Bean Communication
  }
  *Inline Temp
   
  *Remove Control Flag
  class MyClass<T extends Comparable<T>> implements MinMax<T> {
  *Replace Iteration with Recursion
  T[] vals;
*Replace Temp with Query
   
*Use a Connection Pool
  MyClass(T[] o) { vals = o; }
   
  public T min() {
    T v = vals[0];
    for(int i=1; i < vals.length; i++)
      if(vals[i].compareTo(v) < 0) v = vals[i];
   
   
    return v;
  }
  public T max() {
    T v = vals[0];
    for(int i=1; i < vals.length; i++)
      if(vals[i].compareTo(v) > 0) v = vals[i];
    return v;
  }
}
  public class GenIFDemo {
  public static void main(String args[]) {
    Integer inums[] = {3, 6, 2, 8, 6 };
    Character chs[] = {'b', 'r', 'p', 'w' };
    MyClass<Integer> iob = new MyClass<Integer>(inums);
    MyClass<Character> cob = new MyClass<Character>(chs);
    System.out.println("Max value in inums: " + iob.max());
    System.out.println("Min value in inums: " + iob.min());
    System.out.println("Max value in chs: " + cob.max());
    System.out.println("Min value in chs: " + cob.min());
  }
}
Here you can see that MyClass can be used to find the max value of either an Integer array or a character array based on data type used during the declaration of variables iob & cob, hence implementing re-use of code.


*'''Code Reliability Improvement'''
='''Code Reuse in Ruby'''=
A refactoring method will fall under this category if it helps to make the code less prone to errors and adhere more to its intended functionality.
Ruby provides the concept of a module, a container for grouping one or more pieces of code. Modules may hold class definitions, as well as methods and variables that are not part of a specific class. Importantly, they can vary in scale from small snippets to complex software libraries.
*Introduce Assertion
*Introduce A Controller
*Introduce Synchronizer Token
*Reduce Scope of Variable
*Remove Assignments to Parameters


*'''Code Simplification'''
You may not only call specific items of code from a module, but also use an include statement at any point to in your code mix-in all of the code from a named module at that position, as if it had been written at the line where the include statement appears. Code within a module may also call or mix-in from any other modules that are available.
A refactoring method will fall under this category when it causes simplification of the code making it more readable and understandable, it may or may not optimize the execution.  
*Encapsulate Downcast
*Remove Double Negative
*Replace Assignment with Initialization
*Reverse Conditional
*Separate Query from Modifier
*Split Loop
*Substitute Algorithm
*Decompose Conditional


*'''Redundant Code Elimination'''
Combined with class inheritance, modules enable you to organize and reuse code very efficiently both within and between software. Ruby only permits a class to inherit an initial set of methods and attributes from one parent class, but you may freely use module mix-ins within a class definition to supplement the properties and methods that the child class inherits from the parent. When you write your own classes you commonly mix-in the content of built-in Ruby modules such as Enumerable to provide your new class with standard methods.
A refactoring method will fall under this category if it helps to eliminate the unnecessary code
and makes the code cleaner.
*Parametrize Method
*Remove Parameter


*'''Removal of "Type Code"'''
The load path global variable defines the complete set of directories that the runtime should check for source files. This variable is automatically generated at run-time, and you may modify it like any other variable.
A refactory method will fall under the category Removal of "Type Code" if the method helps to remove the type code.
*Replace Type Code with Class
*Replace Type Code with State/Strategy
*Replace Type Code with Subclasses


===Refactoring for Privacy===
=='''RubyGems'''==
A refactoring method will fall under this category if it helps in data protection and privacy.
*Encapsulate Field
*Hide Delegate
*Hide Method
*Hide Presentation Tier-Specific Details from the Business tier
*Introduce Business Delegate
*Wrap Entities with Session


===Dealing with Exceptions===
The RubyGems component of the platform massively extends the code reuse facilities offered by the Ruby language itself. Every library, application, or other collection of files that are configured as a gem may be deployed and upgraded across all systems that have a version of Ruby installed. The public servers at RubyForge provide a global distribution point for Open Source Ruby applications, and you may also offer your own RubyGems server for public or private use, using the supplied tools.
A refactoring method will fall under this category if it optimizes the way the code handles an exception situation.
*Remove Error Code with Exception
*Replace Exception with Test


=References=
=='''Modules & Mixins'''==
http://www.refactoring.com<br>
Module is a collection of methods & constants. The methods in a module maybe instance methods or module methods. Instance methods appear as methods in a class when the module is included, module methods do not. Conversely, module methods may be called an encapsulating object, while instance methods may not.
Refactoring: Improving the Design of Existing Code by Martin Fowler.
 
In the Ruby language a mixin is a class that is mixed with a module. In other words the implementation of the class and module are joined, intertwined, combined, etc. A mixin is a different mechanism to the extend construct used to add concrete implementation to a class. With a mixin you can extend from a module instead of a class.
 
Here is an example of the usage of module & mixins
 
module HealingProperties
def heal_wounds
#do something that heal wounds
end
end
 
class Wolverine
include HealingProperties
def kill_something_with_my_claws!
#Arrr!
end
end
 
logan = Wolverine.new
logan.kill_something_with_my_claws!
logan.heal_wounds
 
 
Module "HealingProperties" has been instantiated in the class "Wolverine". Then code of the Module "HealingProperties" is being used with all the objects of Class "Wolverine", thus providing Code Re-use.
 
='''Conclusion'''=
In the end, reuse is definitely more than the literal meaning of the term. It most certainly implies more than just a quick copy-paste job against other modules. There’s even more to it than simply putting the code in a commonly accessible method, though that’s usually enough for most scenarios.
 
Unfortunately code reuse is not always practical in every case.  Many times it is not even considered when developing a system.  This approach results in a system that is too specific and has too many internal dependencies to be used in other applications.  Real code reuse is also often short circuited by schedule constraints, limited resources and budgetary concerns.  Many well-intentioned development teams know they should start with a reusable design, but the payback for this effort won't be seen until much later.
 
It's also hard to quantify how much code reuse is saving time and money.  You can use tools to count lines of code before and after you implement reused code, but the end result can be misleading.  How do you account for lines you have removed?  Many times you have to rely on developer's opinions as to what percentage of their code was reused.
='''References'''=
http://www.wikipedia.org<br>
http://www.geocities.com/learnprogramming123/Clesson11.htm<br>
http://www.ambysoft.com/essays/typesOfReuse.html<br>
http://www.java2s.com/Code/Java/Language-Basics/Agenericinterfaceexample.htm<br>
http://java-programming.suite101.com/article.cfm/how_to_write_and_reuse_a_java_class<br>
http://www.rubyfleebie.com/an-introduction-to-modules-part-2/<br>
http://www.retrospector.com/2006/05/23/what-code-reuse-really-means/<br>

Latest revision as of 16:13, 12 October 2009

Problem Statement

Different languages have different mechanisms for "code reuse." Assembly and low level languages have macros, C/C++ has includes, Ruby has mixins and modules, Java has packages, and there are many other concepts around reuse and extension. Here is a page that describes the various mechanisms, groups the mechanisms into logical categories, and discusses the advantages and disadvantages of the various schemes, in terms of simplicity, performance, reliability, or other factors.

Code Reuse - A Brief Overview

Code reuse, also called software reuse, is the use of existing software, or software knowledge, to build new software. Code reuse in software development is something assumed literally through re-using bits of code in more than one place. It is truly achieved through using common libraries and interfaces accessible to both the entire application and to other applications in the domain. Here are some of the features of code reuse.

Reuse is not duplication

Duplicating code is the result of a copy-paste scenario. The moment you have copy-pasted a module of code to two locations in your application you’ve just created an additional maintenance point. Also if you have coded a bug into the original code & duplicated it in multiple locations, the bug has now been instantiated in more than one place. Reuse is different from duplication. In code reuse the logic or work that a module does in multiple areas of the application can be reused from one place.The code doesn’t have to physically reside in all of those places to get reused.

Interfaces

Reuse is not always functional code that needs to be applied in more than one place. It can be obtained through the use of interfaces and generics as well. By using a solid interface design to allow any type of object with a compatible set of methods to be used in a piece of your application, you allow for everything on both sides of that interface to be easily interchangeable. Other type of interface-like methods that promote architectural reuse are generics, tag libraries, and dozens of frameworks out there that allow pieces to be easily decoupled and injected into the application.

Advantages of Code Reuse

  • Reusing code saves programming time, which reduces costs.
  • Sharing code can help prevent bugs by reducing the amount of code that needs to be written to perform a task. The shared code can also be tested separately from the end applications.
  • Separating code into common libraries lets programmers specialize in their particular strengths. A security library, for example, can be built by security experts while a user interface which uses the library can let UI experts focus on their tasks.
  • Delegation of tasks into shared modules allows offloading of some functionality onto separate systems.

Drawbacks

  • Maintenance nightmare – If for any reason one to make changes in the copied section, changes have to be made ALL the copies.
  • Unorganized – Reused code tends to be unorganized .It may generate create massive amounts of code which is difficult to decipher after a while.

Examples of Effective Code Reuse

  • Google Chrome is an excellent example of code reuse, it uses at least 25 different software Libraries.
  • Matlab programs are also a good example of code reuse where one reuses different functions from the matlab tool box.

General Methods for Code Reuse in Object Oriented Languages

The types of Code Reuse used for the Object Oriented Framework are as follows:

  • Architected Reuse: The identification, development, and support of large-scale, reusable assets via enterprise architecture. Your enterprise architecture may define reusable domain components, collections of related domain/business classes that work together to support a cohesive set of responsibilities, or service domains which bundle a cohesive collection of services together.
  • Pattern Reuse: The use of documented approaches to solving common problems within a specified context. With pattern reuse you’re not reusing code, instead you are reusing the thinking that goes behind the code. Patterns can be a multiple levels such as analysis, design, and architecture are the most common.
  • Framework Reuse: The use of collections of classes that together implement the basic functionality of a common technical or business domain.Horizontal frameworks, such as a security framework or user interface framework such as the Java Foundation Class (JFC) library and vertical frameworks, such as a financial services framework, are common.
  • Artifact Reuse: The use of previously created development artifacts such as use of cases, standards documents, domain-specific models, procedures and guidelines, and even other applications such as a commercial off the shelf (COTS) package to give one a kick start on a new project.
  • Module Reuse. The use of pre-built, fully encapsulated "modules", components, services, or code libraries in the development of an application. A module is self sufficient and encapsulates only one concept. Module reuse differs from code reuse as one don’t to have access to the source code.
  • Template Reuse. The practice of using a common set of layouts for key development artifacts such as documents, models, and source code within an organization.
  • Code Reuse. The reuse of source code within sections of an application and potentially across multiple applications. At its best code reuse is accomplished through the sharing of common classes and/or collections of functions and procedures. At its worst code reuse is accomplished by copying and then modifying existing code causing a maintenance nightmare.

The Page now talks about reuse in different languages such as C, C++, Java & Ruby.

Code Reuse in C/C++

Functions

(Applicable for both C/C++)

Instead of writing a same function multiple times, we can call the function, thus making the code more concise, readable & modular. Another way of using functions is to write them in header files & then including the header files in the code. Later the functions written in the Header File can be called directly from the main program.

Different Types of Header Files used in C/C++ are as follows:

  • assert.h, math.h, string.h, stdio.h, time.h etc

Simple Program to Illustrate C Functions:

#include <stdio.h>
void print_message(void);
{
printf("Hello World \n");
}

Main Program

int main(void)
{
print_message();
return 0;
}

Classes

(Applicable only for C++, Java)

Classes define methods which process the data present in multiple objects. Thus the same method code gets re-used for all the objects of the class, thus providing code re-use. C++ also defines other features for classes which promote code reuse. Eg: Funtion overloading helps the same function to perform different operations based on the parameters passed to it, thus allowing the use of one function to do multiple tasks.

An simple example of an class is as follows:-

// classes example
#include <iostream>
using namespace std;
class CRectangle {
 int x, y;
public:
 void set_values (int,int);
 void set_values (int);
 int area (int x) {return (x*x);} 
 int area (int x, int y) {return (x*y);}
 };
void CRectangle::set_values (int a, int b) {
x = a;
y = b;
}
void CRectangle::set_values (int a) {
x = a;
}
int main () {
CRectangle rect;
rect.set_values (5,4);
cout << "area: " << rect.area();  //Output = 20
rect.set_values (3,4);
cout << "area: " << rect.area();  //Output = 12
CRectangle sqr;
sqr.set_values (7);
cout << "area: " << sqr.area(); //Output = 49 : Example of Function Overloading & Classes.
return 0;
}

Inheritence

(Applicable for C++, Java)

Derived Classes can reuse code from super class hierarchy. Variables and methods from the super class get added to the derived class, thus preventing duplication of code & enabling code re-use. The derived class can also have some extra methods/variables added to it if required. C++ also supports multiple inheritance where a base class extends more than one class.

class exforsys
 {
public:
exforsys(void) { x=0; }
void f(int n1)
 {
x= n1*5;
 }
void output(void) { cout<<x; }
private: int x;
 };
class sample: public exforsys
 {
public:
sample(void) { s1=0; }
void f1(int n1)
 {
s1=n1*10;
 }
void output(void)
 {
exforsys::output();
cout << s1;
 }
private: int s1;
 };
int main(void)
 {
sample s;
s.f(10);
s.output();
s.f1(20);
s.output();
 }

Libraries

(Aplicable for C++ only)

Standard C++ Libraries are a collection of functions, constants, classes, objects & templates which extend the C++ language providing basic functionality to perform several tasks. Eg: Classes to interact with OS, Data containers, Iterators to operate them & algorithms commonly needed.

Some of the few C++ Standard Template Libraries(STL) are as as follows:

  • Containers Library eg: Bitset, Deqeue, List, Map, Queue, Vector.
  • Iterators Library eg: Iterator

Code Reuse in Java

Some of the code reuse techniques such as Classes, Function Overloading & Inheritance are common for the Java Programming Language as well. Though there will some differences such as: Java doesn't support multiple inheritance like C++. Java makes use of Interfaces & Abstract Classes to achieve Multiple Inheritance.

Re-using Java Classes

The code for a class can now be reused in other class by making use of the new method. Here is an example of the same:

public class helloworld_use {
public static void main(String args[]) {
helloworld myhello = new helloworld();
myhello.greeting_text = "Hello again";
System.out.println(myhello.greeting());
}
}

The code can be compiled and run:

javac helloworld_use.java
java helloworld_use

The end result is the words "Hello again" written to the screen, but the key thing here is that the new application requires no new code to be written for that to happen.

Inheritance and Interfaces

Interfaces are a definition which decide the methods that need to be declared/used in a class. Interfaces are essential to the Java language. They provide for multiple inheritance as well as information hiding and code re-use. Interfaces have advantages over classes because of improved information hiding and code re-use. A very clean design might use interfaces instead of base classes.Inheritance & Interfaces can be used together to implement code reuse.Here is an generic example of an interfaces.


interface MinMax<T extends Comparable<T>> { 
 T min(); 
 T max(); 
} 

class MyClass<T extends Comparable<T>> implements MinMax<T> { 
 T[] vals; 

 MyClass(T[] o) { vals = o; } 

 public T min() { 
   T v = vals[0]; 
   for(int i=1; i < vals.length; i++) 
     if(vals[i].compareTo(v) < 0) v = vals[i]; 

   return v; 
 } 

 public T max() { 
   T v = vals[0]; 

   for(int i=1; i < vals.length; i++) 
     if(vals[i].compareTo(v) > 0) v = vals[i]; 

   return v; 
 } 
} 

 public class GenIFDemo { 
 public static void main(String args[]) { 
   Integer inums[] = {3, 6, 2, 8, 6 }; 
   Character chs[] = {'b', 'r', 'p', 'w' }; 

   MyClass<Integer> iob = new MyClass<Integer>(inums); 
   MyClass<Character> cob = new MyClass<Character>(chs); 

   System.out.println("Max value in inums: " + iob.max()); 
   System.out.println("Min value in inums: " + iob.min()); 

   System.out.println("Max value in chs: " + cob.max()); 
   System.out.println("Min value in chs: " + cob.min()); 
 } 
}

Here you can see that MyClass can be used to find the max value of either an Integer array or a character array based on data type used during the declaration of variables iob & cob, hence implementing re-use of code.

Code Reuse in Ruby

Ruby provides the concept of a module, a container for grouping one or more pieces of code. Modules may hold class definitions, as well as methods and variables that are not part of a specific class. Importantly, they can vary in scale from small snippets to complex software libraries.

You may not only call specific items of code from a module, but also use an include statement at any point to in your code mix-in all of the code from a named module at that position, as if it had been written at the line where the include statement appears. Code within a module may also call or mix-in from any other modules that are available.

Combined with class inheritance, modules enable you to organize and reuse code very efficiently both within and between software. Ruby only permits a class to inherit an initial set of methods and attributes from one parent class, but you may freely use module mix-ins within a class definition to supplement the properties and methods that the child class inherits from the parent. When you write your own classes you commonly mix-in the content of built-in Ruby modules such as Enumerable to provide your new class with standard methods.

The load path global variable defines the complete set of directories that the runtime should check for source files. This variable is automatically generated at run-time, and you may modify it like any other variable.

RubyGems

The RubyGems component of the platform massively extends the code reuse facilities offered by the Ruby language itself. Every library, application, or other collection of files that are configured as a gem may be deployed and upgraded across all systems that have a version of Ruby installed. The public servers at RubyForge provide a global distribution point for Open Source Ruby applications, and you may also offer your own RubyGems server for public or private use, using the supplied tools.

Modules & Mixins

Module is a collection of methods & constants. The methods in a module maybe instance methods or module methods. Instance methods appear as methods in a class when the module is included, module methods do not. Conversely, module methods may be called an encapsulating object, while instance methods may not.

In the Ruby language a mixin is a class that is mixed with a module. In other words the implementation of the class and module are joined, intertwined, combined, etc. A mixin is a different mechanism to the extend construct used to add concrete implementation to a class. With a mixin you can extend from a module instead of a class.

Here is an example of the usage of module & mixins

module HealingProperties
def heal_wounds
#do something that heal wounds
end
end
 
class Wolverine
include HealingProperties
def kill_something_with_my_claws!
#Arrr!
end
end
 
logan = Wolverine.new
logan.kill_something_with_my_claws!
logan.heal_wounds


Module "HealingProperties" has been instantiated in the class "Wolverine". Then code of the Module "HealingProperties" is being used with all the objects of Class "Wolverine", thus providing Code Re-use.

Conclusion

In the end, reuse is definitely more than the literal meaning of the term. It most certainly implies more than just a quick copy-paste job against other modules. There’s even more to it than simply putting the code in a commonly accessible method, though that’s usually enough for most scenarios.

Unfortunately code reuse is not always practical in every case. Many times it is not even considered when developing a system. This approach results in a system that is too specific and has too many internal dependencies to be used in other applications. Real code reuse is also often short circuited by schedule constraints, limited resources and budgetary concerns. Many well-intentioned development teams know they should start with a reusable design, but the payback for this effort won't be seen until much later.

It's also hard to quantify how much code reuse is saving time and money. You can use tools to count lines of code before and after you implement reused code, but the end result can be misleading. How do you account for lines you have removed? Many times you have to rely on developer's opinions as to what percentage of their code was reused.

References

http://www.wikipedia.org
http://www.geocities.com/learnprogramming123/Clesson11.htm
http://www.ambysoft.com/essays/typesOfReuse.html
http://www.java2s.com/Code/Java/Language-Basics/Agenericinterfaceexample.htm
http://java-programming.suite101.com/article.cfm/how_to_write_and_reuse_a_java_class
http://www.rubyfleebie.com/an-introduction-to-modules-part-2/
http://www.retrospector.com/2006/05/23/what-code-reuse-really-means/