CSC/ECE 517 Fall 2012/ch1 1w7 am: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
 
(97 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<p>Code Reuse</p>
<p>Code Reuse - This page describes what is code reuse, how to achieve it and discusses the advantages and disadvantages of code reuse.</p>


== Definition ==
== Definition ==
Code reuse is the way in which an existing code can be used to perform a specific service regardless of the application in which it is used.
Code reuse is the way in which an existing code can be used to perform a specific service regardless of the application in which it is used.<ref name = wiki_code_reuse/> It involves the use of some previously constructed [http://en.wikipedia.org/wiki/Software software] artifacts like source code, library, components, etc. An example of it can be the design patterns in a new context or in a new development project.
It involves the use of some previously constructed software artifacts like source code, library, components, etc. An example of it can be the design patterns in a new context or in a new development project.


Software reuse is the process of creating software systems from existing software rather than building software systems from scratch.
Software reuse is the process of creating software systems from existing software rather than building software systems from scratch.<ref name = "definition_software_reuse" />


== Overview ==
== Overview <ref name = wiki_code_reuse/>==
Code reuse is the idea that a partial computer program written at one time can be, should be, or is being used in another program written at a later time. The reuse of programming code is a common technique which attempts to save time and energy by reducing redundant work.
Code reuse is the idea that a partial computer program written at one time can be, should be, or is being used in another program written at a later time. The reuse of programming code is a common technique which attempts to save time and energy by reducing redundant work.
The software library is a good example of code reuse. Programmers may decide to create internal abstractions so that certain parts of their program can be reused, or may create custom libraries for their own use.
 
The software library is a good example of code reuse.  
 
Programmers may decide to create internal [http://en.wikipedia.org/wiki/Abstraction_%28computer_science%29 abstractions] so that certain parts of their program can be reused, or may create custom libraries for their own use.
 
The general practice of using a prior version of an extant program as a starting point for the next version, is also a form of code reuse.
The general practice of using a prior version of an extant program as a starting point for the next version, is also a form of code reuse.
Some so-called code "reuse" involves simply copying some or all of the code from an existing program into a new one. While organizations can realize time to market benefits for a new product with this approach, they can subsequently be saddled with many of the same code duplication problems caused by cut and paste programming.
 
Many researchers have worked to make reuse faster, easier, more systematic, and an integral part of the normal process of programming. These are some of the main goals behind the invention of object-oriented programming, which became one of the most common forms of formalized reuse. A somewhat later invention is generic programming.
Some so-called code "reuse" involves simply copying some or all of the code from an existing program into a new one. While organizations can realize time to market benefits for a new product with this approach, they can subsequently be saddled with many of the same code duplication problems caused by [http://en.wikipedia.org/wiki/Cut_and_paste_programming cut and paste programming].
Another, newer means is to use software "generators", programs which can create new programs of a certain type, based on a set of parameters that users choose. Fields of study about such systems are generative programming and metaprogramming.
 
Many researchers have worked to make reuse faster, easier, more systematic, and an integral part of the normal process of programming. These are some of the main goals behind the invention of [http://en.wikipedia.org/wiki/Object-oriented_programming object-oriented programming], which became one of the most common forms of formalized reuse.
 
A somewhat later invention is [http://en.wikipedia.org/wiki/Generic_programming generic programming].
 
Another, newer means is to use software "[http://en.wikipedia.org/wiki/Source_code_generation generators]", programs which can create new programs of a certain type, based on a set of parameters that users choose. Fields of study about such systems are [http://en.wikipedia.org/wiki/Generative_programming generative programming] and [http://en.wikipedia.org/wiki/Meta_programming meta programming].


== History ==
== History ==
Ad hoc code reuse has been practiced from the earliest days of programming. Programmers have always reused sections of code, templates, functions, and procedures. Software reuse as a recognized area of study in software engineering, however, dates only from 1968 when Douglas McIlroy of Bell Laboratories proposed basing the software industry on reusable components.  
[http://en.wikipedia.org/wiki/Ad_hoc Ad hoc] code reuse has been practiced from the earliest days of programming. Programmers have always reused sections of code, templates, functions, and [http://en.wikipedia.org/wiki/Procedure_%28computer_science%29 procedures]. Software reuse as a recognized area of study in software engineering, however, dates only from 1968 when [http://en.wikipedia.org/wiki/Douglas_McIlroy Douglas McIlroy] of [http://en.wikipedia.org/wiki/Bell_Labs Bell Laboratories] proposed basing the software industry on reusable components. <ref name = wiki_code_reuse/>


There are many dimensions along which we can trace the history of reuse:
There are many dimensions along which we can trace the history of reuse: <ref name = history_pros_cons/>
* Software Development Life Cycle (SDLC) Model
* [http://en.wikipedia.org/wiki/Software_Development_Life_Cycle Software Development Life Cycle] (SDLC) Model  
* Prototyping, Iterative, ESP, etc.
* [http://en.wikipedia.org/wiki/Prototyping Prototyping], Iterative, ESP, etc.
* Requirements/Specification Method
* Requirements/Specification Method
* Business Model
* Business Model
* Implementation technology
* Implementation technology
=== History of software reuse based on implementation technology dimension ===
=== History of software reuse based on implementation technology dimension <ref name = history_pros_cons/>===
Mid 1980’s
* Mid 1980’s - Mature Third Generation Programming Languages -
Mature Third Generation Programming Languages
Third generation languages were more portable than the earlier machine specific languages; even though source code still had to be language, [http://en.wikipedia.org/wiki/Operating_system OS] and platform specific. However they did achieve limited source code reuse for high value. e.g. math libraries.
Late 1980’s
Early Object Oriented Languages and SQL DB
Early 1990’s
Mature OO Languages, Source Code Libraries
Mid 1990’s
Early DIAE Component Packaging
Late 1990’s
Mature DIAE Components, Cross-Protocol Bridges
2000-2005
Early Service Oriented Architecture Products


== Types of Code reuse ==
* Late 1980’s - Early Object Oriented Languages and SQL DB -
Introduction of object oriented languages like [http://en.wikipedia.org/wiki/Common_Lisp_Object_System Common Lisp Object System (CLOS)], C++ interpreter, etc provided encapsulation and packaging technology.Packaging and common object models promoted development of language “bindings”. Systematic and repeatable object oriented development processes were also introduced during this time. Although most [http://en.wikipedia.org/wiki/Portability_%28computer_science%29 portability] constraints remained as they were, some reuse success was achieved in the form of high value data structure libraries (e.g. GRACE and Booch parts). The first successful reusable service of SQL [http://en.wikipedia.org/wiki/Relational_database_management_system RDBMS] was developed during this period.


=== Reuse over fungible systems ===
* Early 1990’s - Mature OO Languages, Source Code Libraries -
portability
This era saw development of mature OO languages like [http://en.wikipedia.org/wiki/Smalltalk Smalltalk], ANSI [http://en.wikipedia.org/wiki/CLOS CLOS], C++ compilers, [http://en.wikipedia.org/wiki/GUI GUI] and [http://en.wikipedia.org/wiki/Event_driven_programming Event Driven Programming] Libraries and portable compiled software packages like Shared Libraries, Dynamic Link Libraries, etc. Significant reuse research was carried out during this period(e.g. SPC CoE for Reuse/ARPA contract) which gave birth to early software reuse driven processes and reuse libraries (like management systems, not just content)
commonality
ex: numeric types of fixed range and/or precision


=== Reuse over different domains ===
* Mid 1990’s - Early DIAE Component Packaging -
inheritance and binding
Dynamically Integrable Autonomously Executable Components that are compiled and linked separately, integrate at run time, and run independent of each other were developed during this period. (e.g. COM and CORBA). Distributed systems which formed the foundation for [http://en.wikipedia.org/wiki/Web_services Web Services] and [http://en.wikipedia.org/wiki/Component-based_development Component Based development processes] were introduced.
generality and instantiation
Advances like these also gave rise to commercially successful code generators like Netron, Frame Technology and reusable component vendors like [http://en.wikipedia.org/wiki/Infragistics Infragistics].
ex: object oriented programming, generics, templates, unconstrained types


=== Reuse over time ===
* Late 1990’s - Mature DIAE Components, Cross-Protocol Bridges -
maintenance
Along with introduction of Cross Protocol Bridges which allow [http://en.wikipedia.org/wiki/COM_%28hardware_interface%29 COM] and [http://en.wikipedia.org/wiki/Cobra_%28programming_language%29 CORBA] systems to participate in the same system, Light weight integration protocols like [http://en.wikipedia.org/wiki/SOAP SOAP] were introduced in this period. New reusable component packaging mechanisms were invented. Reuse based development processes matured with time and specialized reusable component market got established.
evolution
versions
ex:product lines to be updated over time (such as the 360 family), updating programs for the year 2000


== Examples ==
* 2000-2005 - Early [http://en.wikipedia.org/wiki/Service_Oriented_Architecture Service Oriented Architecture] Products -
This era saw rise of Service Oriented Architecture and rediscovery of reuse research like Software Reuse (Asset) Management Systems, Domain Specific Reuse, Domain Languages (Software Factories), etc.
It was understood that reuse must reuse more than just code and it would require drastic process changes. [http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29 Design patterns] were also created during this time.
Reuse Successes during time include - Microsoft .Net Framework, SRMS: Flashline and LogicLibrary.


Adding Proc Near ; Declaration of the procedure
== Techniques <ref name = techniques/>==
Mov Bx, 0 ; Content of the procedure
In re-using code, we have several levels of granularity
Mov B1, Ah
Mov Ah, 00
Add Bx, Ax
Ret ; Return directive
Add Endp ; End of procedure declaration


and an example of Macro:  
=== Single lines of code ===
For example, in [http://en.wikipedia.org/wiki/Ruby_%28programming_language%29 Ruby] to print an array containing 5 elements we simply use the following
<pre>
[ 'Sam', 'John', 'Gita' ].each {|name| print name, " " }
</pre>
outputs :
Sam John Gita.


=== Procedures, Macros ===
Procedures and macros are the low level code reuse techniques
A macro is a group of repetitive instructions in a program which are codified only once and can be used as many times
as necessary.
<pre>
Position MACRO Row, Column  
Position MACRO Row, Column  
PUSH AX  
PUSH AX  
Line 82: Line 84:
POP AX  
POP AX  
ENDM
ENDM
Related
</pre>
A procedure is a collection of instructions to which we can direct the flow of our program, and once the execution of these instructions is over control is given back to the next line to process of the code which called on the procedure.
<pre>


== Techniques ==
Adding Proc Near ; Declaration of the procedure
 
Mov Bx, 0 ; Content of the procedure
In re-using code, we have several levels of granularity
Mov B1, Ah
Mov Ah, 00
Add Bx, Ax
Ret ; Return directive
Add Endp ; End of procedure declaration


* Single lines of code -
</pre>
For example, in Ruby to print an array containing 5 elements we simply use the following
[ 'Sam', 'John', 'Gita' ].each {|name| print name, " " }
outputs :
Sam John Gita.


* Functions/procedures
=== Functions/methods ===
For example, in Ruby a procedure can be written as  
For example, in Ruby a method can be written as follows
<source>
<pre>
def convert_to_faren(name)
def convert_to_farenhite(temperature_in_celcius)
result = "Good night, " + name
result = temperature_in_celcius * (9/5) +32
return result
return result
end
end
</source>
</pre>
 
=== Components ===
When you are building software, objects are created in code, and reusable objects that perform specific services in different circumstances are called components.
When you use Microsoft® Office to build custom applications, you write code that leverages the power of Office components. Using an Office component means you are not only excused from writing the code yourself, but you are using a component that has been tested and found reliable in different conditions.
 
=== Object orientation <ref name = Object_orinetation />===
High level languages also come with effective abstractions to build and share "abstract data types" and other "reusable libraries". Source code components are generally intended to be used as black-boxes: a public interface of usage is announced, formally or not (ruby has not equivalent of java interfaces, for example), while the realization of this interface is kept hidden (or at least intended to be). Think to C libraries, java's .jars, python's modules, ruby's gems, and so on. In many languages, "find a component, download it, and go" has become a reality!


* Modules
==== Packages ====
* Components
A Java package is a mechanism for organizing Java classes into namespaces similar to the modules of Modula. Java packages can be stored in compressed files called [http://en.wikipedia.org/wiki/JAR_%28file_format%29 JAR] files, allowing classes to download faster as a group rather than one at a time. Programmers also typically use packages to organize classes belonging to the same category or providing similar functionality.
* Packages
A package provides a unique namespace for the types it contains.
* Subsystems
Classes in the same package can access each other's package-access members.
* Entire programs


=== procedures, macros ===
==== Modules ====  
Procedures and macros are the low level code reuse techniques
Modules are a way of grouping together methods, classes, and constants. An example of a Ruby module is as follows
A macro is a group of repetitive instructions in a program which are codified only once and can be used as many times
<pre>
as necessary.  
module Trig
A procedure is a collection of instructions to which we can direct the flow of our program, and once the execution of these instructions is over control is given back to the next line to process of the code which called on the procedure.
PI = 3.141592654
def Trig.sin(x)
# ..
end
def Trig.cos(x)
# ..
end
</pre>


=== High level languages ===
====[http://en.wikipedia.org/wiki/Inheritance_%28computer_science%29 Inheritance] ====  
Functions, subroutines, libraries
In object-oriented programming (OOP), inheritance is a way to reuse code of existing objects, or to establish a subtype from an existing object, or both, depending upon programming language support. In classical inheritance where objects are defined by classes, classes can inherit attributes and behavior from pre-existing classes called base classes, [http://en.wikipedia.org/wiki/Superclass_%28computer_science%29#Subclasses_and_superclasses superclasses], parent classes or ancestor classes. The resulting classes are known as derived classes, subclasses or child classes. The relationships of classes through inheritance gives rise to a hierarchy. The basic mechanism of subclassing is simple. The child inherits all of the capabilities of its parent class — all the parent’s instance methods are available in instances of the child. Let’s look at a trivial example and then later build on it.


=== Object Oriented Languages ===
Here’s a definition of a parent class: <pre>
Mixin, Object orientation, inheritance
class Parent
def say_hello
puts "Hello from #{self}"
end
end


=== generators ===
p = Parent.new
Reusable code is code that can be used, without modification, to perform a spectific service regardless of what application uses the code.
p.say_hello


There are everyday objects that perform a specific service in different circumstances all around you. Think of a calendar. It gives you the ability to look up days and dates. You can use it to determine that this year your birthday falls on a Tuesday, or that Thanksgiving is on the 25th, or that there are two extra days to file tax returns because April 15 is on a Saturday. When you are building software, objects are created in code, and reusable objects that perform specific services in different circumstances are called components.
</pre>
Some characteristics that make software more easily reusable are modularity, loose coupling, high cohesion, information hiding and separation of concerns.
Output:
For newly written code to use a piece of existing code, some kind of interface, or means of communication, must be defined. These commonly include a "call" or use of a subroutine, object, class, or prototype. In organizations, such practices are formalized and standardized by domain engineering aka software product line engineering.
Hello from #<Parent:0x0a40c4>


Nowadays, no one would seriously argue that software reuse has failed to become a standard software engineering practice. Let have a quick look at each of the technique mentioned in the paper, in the light of the tools we have today. Note that I've tried to be consistent with the paper, in terms of the software abstractions behind each reuse technique. Some of the terms used in the paper may have a slightly different meaning today. Also note that the different techniques may overlap, as already pointed implicitly by Krueger himself. I must add that the presentation order I've chosen is related to my own understanding of the concepts ;-) Therefore, all subtitles and some other links below can be used easily to launch a google search!
and a child class that inherits from it:
High Level Languages
<pre>
# Subclass the parent...
class Child < Parent
end
c = Child.new
c.say_hello


Java, Clojure, Ruby, Haskell, and so on. High level languages are numerous and various. Each one comes with its set of tools to raise the abstraction level (sometimes in certain respects only, like providing good abstractions for concurrency, or low-level tasks).
</pre>
Source code components


High level languages also come with effective abstractions to build and share "abstract data types" and other "reusable libraries". Source code components are generally intended to be used as black-boxes: a public interface of usage is announced, formally or not (ruby has not equivalent of java interfaces, for example), while the realization of this interface is kept hidden (or at least intended to be). Think to C libraries, java's .jars, python's modules, ruby's gems, and so on. In many languages, "find a component, download it, and go" has become a reality!
Output:
Software architectures
Hello from #<Child:0x0a3d68>


Software architectures are large-grain software frameworks. In contrast with source code components which are often black-boxes, software architecture are designed as grey-boxes: they are intended to be extended and provide specific extension points for this. We have a lot of reusable frameworks nowadays. Probably the most common are web frameworks (Ruby on Rails, django, ASP.net, ...), integrated development environment (IDE, Eclipse is worth mentioning due to its architecture), service oriented architectures (SOA), and so on.
The parent class defines a single instance method, say_hello. We call it by creating a new
Design and code scavenging
instance of the class and store a reference to that instance in the variable p.
We then create a subclass using class Child < Parent. The < notation means we’re creating a
subclass of the thing on the right; the fact that we use less-than presumably signals that the
child class is supposed to be a specialization of the parent.
Note that the child class defines no methods, but when we create an instance of it, we can
call say_hello. That’s because the child inherits all the methods of its parent. Note also that
when we output the value of self — the current object - it shows that we’re in an instance of
class Child, even though the method we’re running is defined in the parent.


Design and code scavenging is simply a form of "find, copy-paste, adapt". The well-known design patterns[3] provide an organized form of design scavenging, by providing catalogues for applying such kind of reuse. Even if invented in the context of the object-oriented programming, design patterns had a great impact far beyond that programming paradigm.
===Generators<ref name = generators/>===
Source code generation is the act of generating source code based on an [http://en.wikipedia.org/wiki/Ontology_%28information_science%29 ontological] model such as a template and is accomplished with a programming tool such as a template processor or an [http://en.wikipedia.org/wiki/Integrated_development_environment IDE]. These tools allow the generation of source code through any of various means. A macro processor, such as the C preprocessor, which replaces patterns in source code according to relatively simple rules, is a simple form of source code generator. [http://en.wikipedia.org/wiki/Parser Parser] generators (lex & yacc, antlr, rats!, treetop, pyPEG, and so on.) are probably the best-known examples of application generators. Other examples include [http://en.wikipedia.org/wiki/Wizard_%28software%29 wizards] that one can find in Integrated Development Environments (to design and generate code of user interfaces, for example), tools that generate classes from UML class diagrams, generators of database schemas, report generators, etc.


Code scavenging is less organized as few such catalogues exists. Every day however, the web gives use better ways to apply such a reuse technique: google code search, github's gist, pastie, and so on. I also remember having read an book about Eclipse[4] whose authors encouraged applying the monkey see, monkey do rule, that is, copy pasting code from other Eclipse plugins whose source code is available.
===Software architectures===
Application generators
Software architectures are large-grain software frameworks. In contrast with source code components which are often black-boxes, software architecture are designed as grey-boxes: they are intended to be extended and provide specific extension points for this. We have a lot of reusable frameworks nowadays. Probably the most common are web frameworks (Ruby on Rails, django, ASP.net, ...), integrated development environment (IDE, Eclipse is worth mentioning due to its architecture), service oriented architectures (SOA), and so on.


The paper compares application generators with software compilers. According to it, generators differ from compilers in that the input specifications are typically very high level, special-purpose abstractions from a very narrow application domain. I would add that compilers traditionnaly transform source code from a high-level language to something which is intended to be executable by a (virtual) machine, while application generators transform (very) high level descriptions into code that generally need to be compiled in turn.
===Design and code scavenging===
Design and code scavenging is simply a form of "find, copy-paste, adapt". The well-known [http://en.wikipedia.org/wiki/Software_design_pattern design patterns] provide an organized form of design scavenging, by providing catalogs for applying such kind of reuse. Even if invented in the context of the object-oriented programming, design patterns had a great impact far beyond that programming [http://en.wikipedia.org/wiki/Paradigm paradigm].


In that sense, parser generators (lex & yacc, antlr, rats!, treetop, pyPEG, and so on.) are probably the best-known examples of application generators. Other examples include wizards that one can find in Integrated Development Environments (to design and generate code of user interfaces, for example), tools that generate classes from UML class diagrams, generators of database schemas, report generators, etc. In note in passing that the Noe library I was talking about recently is of course a kind of application generator.
Code scavenging is less organized as few such catalogs exists. Every day however, the web gives users better ways to apply reuse techniques such as google code search, github's gist, pastie, and so on.
Transformational systems


===Transformational systems===
Transformational systems are the holy grail of computer science, nothing less! In that paradigm, software developers actually describe the behavior of the software using a high-level specification language (related to VHLL described before). In a second phase, the specifications are transformed in order to produce an executable system. The transformations are meant to enhance efficiency without changing the semantics.
Transformational systems are the holy grail of computer science, nothing less! In that paradigm, software developers actually describe the behavior of the software using a high-level specification language (related to VHLL described before). In a second phase, the specifications are transformed in order to produce an executable system. The transformations are meant to enhance efficiency without changing the semantics.


Transformational systems emphasizes the what instead of the how. They actually bet on the concision of declarative statements over procedural ones to achieve effective reuse. While general purpose transformation systems remain mostly research topics, notable results have been achieved in some specific domains: relational systems come with effective query optimizers, some rapid prototyping approaches uses transformations from high-level descriptions down to code, etc.
Transformational systems emphasizes the what instead of the how. They actually bet on the concision of declarative statements over procedural ones to achieve effective reuse. While general purpose transformation systems remain mostly research topics, notable results have been achieved in some specific domains: relational systems come with effective query optimizers, some rapid prototyping approaches using transformations from high-level descriptions down to code, etc.
Very High Level Languages (VHLL)


Very High Level Languages, also known as executable specification languages, are languages with very high level of abstraction. They are somewhat difficult to capture precisely and may lead to software reuse that is very specific to specialized domains. However, I would say that the recent advent of Domain Specific Languages (DSLs) and good support for them in dynamic languages (ruby, python, clojure, ...) can be seen as promoting and helping building VHLLs.
===Very High Level Languages (VHLL)===
Software schemas
Very High Level Languages, also known as executable specification languages, are languages with very high level of abstraction. They are somewhat difficult to capture precisely and may lead to software reuse that is very specific to specialized domains. However, the recent advent of [http://en.wikipedia.org/wiki/Domain_specific_languages Domain Specific Languages] (DSLs) and good support for them in dynamic languages (ruby, python, clojure, ...) and can be seen as promoting and helping building VHLLs.


I must confess not being familiar with software schemas. The paper states that software schemas are a formal extension to reusable software components . From what I understand, it seems that we are talking about some kind of formal pseudo code, intended to be instantiated in a particular language. Unfortunately, a google search does not return relevant results, at the time of writing. I would like to know if they had an impact on current software engineering practices. So if someone knows something about software schemas, just let me know (see the comment form at bottom of this page), and I'll be happy to update this section!
== Best practices <ref name = best_practices />==
 
== Best practices ==
Here are some of the best practices to be followed to make sure that the code that is being written is reusable.
Here are some of the best practices to be followed to make sure that the code that is being written is reusable.


* The first consideration is to write code that uses a consistent naming convention, that is formatted properly, and that contains useful comments.
* The first consideration is to write code that uses a consistent naming convention, that is formatted properly, and that contains useful comments.
* Examine the code to make sure that all the procedures have a single, specific purpose. Make sure that the procedure can be describedin a short, plain sentence. For example, "This procedure accept two numbers and calculates the product of those two numbers" If a procedure can not be described simply and clearly in a sentence, then it probably does too many things. Break down complicated procedures into smaller ones that do one thing each. Procedures should contain only code that clearly belongs together.
* Examine the code to make sure that all the procedures have a single, specific purpose. Make sure that the procedure can be describedin a short, plain sentence. For example, "This procedure accept two numbers and calculates the product of those two numbers". If a procedure can not be described simply and clearly in a sentence, then it probably does too many things. Break down complicated procedures into smaller ones that do one thing each. Procedures should contain only code that clearly belongs together.
* Avoid making specific reference to named application objects.
* Avoid making specific reference to named application objects.
* Try to minimize the number of arguments in a procedure and pass in only what is actually required by the procedure. In addition, make sure the procedures use all the arguments passed to them.
* Try to minimize the number of arguments in a procedure and pass in only what is actually required by the procedure. In addition, make sure the procedures use all the arguments passed to them.
Line 171: Line 202:
* Communicate between procedures by passing data as arguments to the procedures. Persist data by writing it to disk. Avoid using a procedure to write to a global variable so another procedure can read data from that global variable. Avoid communicating with another procedure by passing data out of the application, for example, using one procedure to write data to a disk file so another procedure can read that data.
* Communicate between procedures by passing data as arguments to the procedures. Persist data by writing it to disk. Avoid using a procedure to write to a global variable so another procedure can read data from that global variable. Avoid communicating with another procedure by passing data out of the application, for example, using one procedure to write data to a disk file so another procedure can read that data.


== Advantages ==
== Advantages <ref name = history_pros_cons/>==
 
* '''Efficiency''' - Software reuse increases the software productivity and decreases the time required for the development of a software by reducing the time spent in designing or in coding
* '''Efficiency''' - Software reuse increases the software productivity and decreases the time required for the development of a software by reducing the time spent in designing or in coding
* '''Standardization''' - By using the technique of software reuse, a company can improve software system interoperability and needs less people for software development. This provides a competitive advantage for the company and helps to produce better quality software and standardized software.
* '''Standardization''' - By using the technique of software reuse, a company can improve software system interoperability and needs less people for software development. This provides a competitive advantage for the company and helps to produce better quality software and standardized software.
* '''Consistency''' - Reuse of UI widgets in MacOS and Win32 leads to common “look-and-feel” between applications
* '''Consistency''' - Reuse of UI [http://en.wikipedia.org/wiki/Software_widget widgets] in MacOS and Win32 leads to common “look-and-feel” between applications
* '''Debugging''' -  
* '''Debugging''' -  
* '''Reliability''' - Systems that incorporate a high level of reusable components are more reliable and more easily constructed. Reused design/code is often tested design/code.
* '''Reliability''' - Systems that incorporate a high level of reusable components are more reliable and more easily constructed. Reused design/code is often tested design/code.
* '''Profit!''' - Software reuse technique helps the company to reduce the costs involved in software development and maintenance.
* '''Profit!''' - Software reuse technique helps the company to reduce the costs involved in software development and maintenance.
* '''Reduced Risk''' - Software reuse also reduces the risk involved in software development process.
* '''Reduced Risk''' - Software reuse also reduces the risk involved in software development process.
* '''Component Market''' - Reuse can lead to a market for component software. Real-world examples: ActiveX components, Hypercard stacks, Java packages, even software tools, such as xerces and xalan from xml.apache.org (they are often included in other software systems)
* '''Component Market''' - Reuse can lead to a market for component software. Real-world examples: [http://en.wikipedia.org/wiki/Activex ActiveX] components, Hypercard stacks, Java packages, even software tools, such as xerces and xalan from xml.apache.org (they are often included in other software systems)


== Trade-offs for code reuse at various levels of components ==
== Trade-offs for code reuse at various levels of components <ref name=trade_offs/>==
Different types of application code require varying levels of investment to achieve successful reuse
Different types of application code require varying levels of investment to achieve successful reuse


* Reusable GUI objects reduce development time and improve quality and consistency but provide only modest payback in terms of overall application development costs.
* Reusable GUI objects reduce development time and improve quality and consistency but provide only modest payback in terms of overall application development costs.
* Server-side components that constitute reusable business logic can provide significant payback but require extensive up-front analysis and design. They also require an architectural foundation but may experience a short shelf life.
* Server-side components that constitute reusable business logic can provide significant payback but require extensive up-front analysis and design. They also require an architectural foundation but may experience a short shelf life.
* Infrastructure components and services frameworks are generic services for transactions, messaging, security, and database connectivity. They eliminate the need to repeatedly build infrastructure that all applications use, but require extensive analysis and design, and complex programming. These standards-based components can often be purchased off-the-shelf.
* Infrastructure components and services frameworks are generic services for transactions, messaging, security, and [http://en.wikipedia.org/wiki/Database database] connectivity. They eliminate the need to repeatedly build infrastructure that all applications use, but require extensive analysis and design, and complex programming. These standards-based components can often be purchased off-the-shelf.
* High-level patterns allow organizations to achieve design reuse and identify components with high reuse potential, but developers must build or acquire the components.
* High-level patterns allow organizations to achieve design reuse and identify components with high reuse potential, but developers must build or acquire the components.
* Packaged applications provide the only guaranteed form of reuse, letting user companies acquire functionality for significantly less than the cost of building it themselves. However, these applications may not offer the exact functionality an organization needs; the subsequent customization that's required will add to the cost.
* Packaged applications provide the only guaranteed form of reuse, letting user companies acquire functionality for significantly less than the cost of building it themselves. However, these applications may not offer the exact functionality an organization needs; the subsequent customization that's required will add to the cost.


== Practical problems ==
== Practical problems <ref name = history_pros_cons/>==
 
Although software reuse provides many benefits for the developers, there are some disadvantages.  
Although software reuse provides many benefits for the developers, there are some disadvantages.  


Line 198: Line 227:
* Mismatch - Reused code or design may not completely match the situation, in that case, reusing the code may incur additional time and effort.  
* Mismatch - Reused code or design may not completely match the situation, in that case, reusing the code may incur additional time and effort.  
* Non-functional characteristics of code may not match the situation - Consider a database that can scale to 10,000s of items, but you need it to scale to 100,000s of items.
* Non-functional characteristics of code may not match the situation - Consider a database that can scale to 10,000s of items, but you need it to scale to 100,000s of items.
* Expense - Some components may be too expensive for the project’s budget. For instance, SGML (a precursor to HTML and XML) tools sell for 5000 dollars a license!
* Expense - Some components may be too expensive for the project’s budget. For instance, [http://en.wikipedia.org/wiki/SGML SGML] (a precursor to [http://en.wikipedia.org/wiki/Html HTML] and [http://en.wikipedia.org/wiki/Xml XML]) tools sell for 5000 dollars a license!


=== Disadvantages for developers who develop reusable code ===
=== Disadvantages for developers who develop reusable code ===
* Building reusable objects requires extensive analysis and design. The developer needs to understand and take into consideration all the generalities while coding the reusable module.
* Building reusable objects requires extensive analysis and design. The developer needs to understand and take into consideration all the generalities while coding the reusable module.
* The developer needs to invest extra time in testing and quality assurance, optimization, and documentation. All this takes time and labor, which increases the cost of the code.  
* The developer needs to invest extra time in testing and [http://en.wikipedia.org/wiki/Quality_assurance quality assurance], optimization, and documentation. All this takes time and labor, which increases the cost of the code.  
* IT departments must also add to the payback equation the cost of tools to support reuse, such as version control and repositories.  
* IT departments must also add to the payback equation the cost of tools to support reuse, such as version control and repositories.  
* The cost of administering an ongoing reuse program must be considered.  
* The cost of administering an ongoing reuse program must be considered.  
With all these elements, it becomes apparent that reuse doesn't come cheap.
With all these elements, it becomes apparent that reuse doesn't come cheap.


== Conclusion ==
== Conclusion ==
The only way you can avoid code depreciation is through reuse but you need to be disciplined and follow a strict process. Reuse enables you to do more with less.
The only way you can avoid code depreciation is through reuse but you need to be disciplined and follow a strict process. Reuse enables you to do more with less.


==See also==
*[http://en.wikipedia.org/wiki/Don%27t_repeat_yourself Don't repeat yourself]
*[http://en.wikipedia.org/wiki/Single_Source_of_Truth Single Source of Truth]
*[http://en.wikipedia.org/wiki/International_Conference_on_Software_Reuse International_Conference_on_Software_Reuse|ICSR]
*[http://en.wikipedia.org/wiki/Language_binding Language binding]
*[http://en.wikipedia.org/wiki/Reuse_metrics Reuse metrics]
*[http://en.wikipedia.org/wiki/Software_framework Software framework]
*[http://en.wikipedia.org/wiki/Type_polymorphism Type polymorphism|Polymorphism]
*[http://en.wikipedia.org/wiki/Virtual_inheritance Virtual inheritance]


== References ==
== References ==
<references>
<ref name = techniques> http://www.revision-zero.org/reuse</ref>
<ref name = definition_software_reuse> http://www.biglever.com/papers/Krueger_AcmReuseSurvey.pdf </ref>
<ref name = history_pros_cons> http://www.cs.colorado.edu/~kena/classes/3308/f04/lectures/lecture10.pdf </ref>
<ref name = wiki_code_reuse> http://en.wikipedia.org/wiki/Code_reuse </ref>
<ref name = trade_offs> http://www.informationweek.com/708/08iuhid.htm </ref>
<ref name = best_practices> http://msdn.microsoft.com/en-us/library/office/aa189298%28v=office.10%29 </ref>
<ref name = Object_orinetation> http://en.wikipedia.org/wiki/Object-oriented_programming </ref>
<ref name = generators> http://en.wikipedia.org/wiki/Generative_programming </ref>


http://www.revision-zero.org/reuse - check references in these
</references>
http://www.biglever.com/papers/Krueger_AcmReuseSurvey.pdf
http://www.codeproject.com/Articles/7746/Value-of-Code-Part-II-Reusing-Code
http://www.inf.ufsc.br/~vilain/framework-thiago/p39-johnson.pdf
http://www.cs.colorado.edu/~kena/classes/3308/f04/lectures/lecture10.pdf
Software Reuse History- Thomas Pole

Latest revision as of 23:20, 21 September 2012

Code Reuse - This page describes what is code reuse, how to achieve it and discusses the advantages and disadvantages of code reuse.

Definition

Code reuse is the way in which an existing code can be used to perform a specific service regardless of the application in which it is used.<ref name = wiki_code_reuse/> It involves the use of some previously constructed software artifacts like source code, library, components, etc. An example of it can be the design patterns in a new context or in a new development project.

Software reuse is the process of creating software systems from existing software rather than building software systems from scratch.<ref name = "definition_software_reuse" />

Overview <ref name = wiki_code_reuse/>

Code reuse is the idea that a partial computer program written at one time can be, should be, or is being used in another program written at a later time. The reuse of programming code is a common technique which attempts to save time and energy by reducing redundant work.

The software library is a good example of code reuse.

Programmers may decide to create internal abstractions so that certain parts of their program can be reused, or may create custom libraries for their own use.

The general practice of using a prior version of an extant program as a starting point for the next version, is also a form of code reuse.

Some so-called code "reuse" involves simply copying some or all of the code from an existing program into a new one. While organizations can realize time to market benefits for a new product with this approach, they can subsequently be saddled with many of the same code duplication problems caused by cut and paste programming.

Many researchers have worked to make reuse faster, easier, more systematic, and an integral part of the normal process of programming. These are some of the main goals behind the invention of object-oriented programming, which became one of the most common forms of formalized reuse.

A somewhat later invention is generic programming.

Another, newer means is to use software "generators", programs which can create new programs of a certain type, based on a set of parameters that users choose. Fields of study about such systems are generative programming and meta programming.

History

Ad hoc code reuse has been practiced from the earliest days of programming. Programmers have always reused sections of code, templates, functions, and procedures. Software reuse as a recognized area of study in software engineering, however, dates only from 1968 when Douglas McIlroy of Bell Laboratories proposed basing the software industry on reusable components. <ref name = wiki_code_reuse/>

There are many dimensions along which we can trace the history of reuse: <ref name = history_pros_cons/>

History of software reuse based on implementation technology dimension <ref name = history_pros_cons/>

  • Mid 1980’s - Mature Third Generation Programming Languages -

Third generation languages were more portable than the earlier machine specific languages; even though source code still had to be language, OS and platform specific. However they did achieve limited source code reuse for high value. e.g. math libraries.

  • Late 1980’s - Early Object Oriented Languages and SQL DB -

Introduction of object oriented languages like Common Lisp Object System (CLOS), C++ interpreter, etc provided encapsulation and packaging technology.Packaging and common object models promoted development of language “bindings”. Systematic and repeatable object oriented development processes were also introduced during this time. Although most portability constraints remained as they were, some reuse success was achieved in the form of high value data structure libraries (e.g. GRACE and Booch parts). The first successful reusable service of SQL RDBMS was developed during this period.

  • Early 1990’s - Mature OO Languages, Source Code Libraries -

This era saw development of mature OO languages like Smalltalk, ANSI CLOS, C++ compilers, GUI and Event Driven Programming Libraries and portable compiled software packages like Shared Libraries, Dynamic Link Libraries, etc. Significant reuse research was carried out during this period(e.g. SPC CoE for Reuse/ARPA contract) which gave birth to early software reuse driven processes and reuse libraries (like management systems, not just content)

  • Mid 1990’s - Early DIAE Component Packaging -

Dynamically Integrable Autonomously Executable Components that are compiled and linked separately, integrate at run time, and run independent of each other were developed during this period. (e.g. COM and CORBA). Distributed systems which formed the foundation for Web Services and Component Based development processes were introduced. Advances like these also gave rise to commercially successful code generators like Netron, Frame Technology and reusable component vendors like Infragistics.

  • Late 1990’s - Mature DIAE Components, Cross-Protocol Bridges -

Along with introduction of Cross Protocol Bridges which allow COM and CORBA systems to participate in the same system, Light weight integration protocols like SOAP were introduced in this period. New reusable component packaging mechanisms were invented. Reuse based development processes matured with time and specialized reusable component market got established.

This era saw rise of Service Oriented Architecture and rediscovery of reuse research like Software Reuse (Asset) Management Systems, Domain Specific Reuse, Domain Languages (Software Factories), etc. It was understood that reuse must reuse more than just code and it would require drastic process changes. Design patterns were also created during this time. Reuse Successes during time include - Microsoft .Net Framework, SRMS: Flashline and LogicLibrary.

Techniques <ref name = techniques/>

In re-using code, we have several levels of granularity

Single lines of code

For example, in Ruby to print an array containing 5 elements we simply use the following

[ 'Sam', 'John', 'Gita' ].each {|name| print name, " " }

outputs : Sam John Gita.

Procedures, Macros

Procedures and macros are the low level code reuse techniques A macro is a group of repetitive instructions in a program which are codified only once and can be used as many times as necessary.

Position MACRO Row, Column 
PUSH AX 
PUSH BX 
PUSH DX 
MOV AH, 02H 
MOV DH, Row 
MOV DL, Column 
MOV BH, 0 
INT 10H 
POP DX 
POP BX 
POP AX 
ENDM

A procedure is a collection of instructions to which we can direct the flow of our program, and once the execution of these instructions is over control is given back to the next line to process of the code which called on the procedure.


Adding Proc Near ; Declaration of the procedure 
Mov Bx, 0 ; Content of the procedure 
Mov B1, Ah 
Mov Ah, 00 
Add Bx, Ax 
Ret ; Return directive 
Add Endp ; End of procedure declaration 

Functions/methods

For example, in Ruby a method can be written as follows

def convert_to_farenhite(temperature_in_celcius)
result = temperature_in_celcius * (9/5) +32
return result
end

Components

When you are building software, objects are created in code, and reusable objects that perform specific services in different circumstances are called components. When you use Microsoft® Office to build custom applications, you write code that leverages the power of Office components. Using an Office component means you are not only excused from writing the code yourself, but you are using a component that has been tested and found reliable in different conditions.

Object orientation <ref name = Object_orinetation />

High level languages also come with effective abstractions to build and share "abstract data types" and other "reusable libraries". Source code components are generally intended to be used as black-boxes: a public interface of usage is announced, formally or not (ruby has not equivalent of java interfaces, for example), while the realization of this interface is kept hidden (or at least intended to be). Think to C libraries, java's .jars, python's modules, ruby's gems, and so on. In many languages, "find a component, download it, and go" has become a reality!

Packages

A Java package is a mechanism for organizing Java classes into namespaces similar to the modules of Modula. Java packages can be stored in compressed files called JAR files, allowing classes to download faster as a group rather than one at a time. Programmers also typically use packages to organize classes belonging to the same category or providing similar functionality. A package provides a unique namespace for the types it contains. Classes in the same package can access each other's package-access members.

Modules

Modules are a way of grouping together methods, classes, and constants. An example of a Ruby module is as follows

module Trig
PI = 3.141592654
def Trig.sin(x)
# ..
end
def Trig.cos(x)
# ..
end

Inheritance

In object-oriented programming (OOP), inheritance is a way to reuse code of existing objects, or to establish a subtype from an existing object, or both, depending upon programming language support. In classical inheritance where objects are defined by classes, classes can inherit attributes and behavior from pre-existing classes called base classes, superclasses, parent classes or ancestor classes. The resulting classes are known as derived classes, subclasses or child classes. The relationships of classes through inheritance gives rise to a hierarchy. The basic mechanism of subclassing is simple. The child inherits all of the capabilities of its parent class — all the parent’s instance methods are available in instances of the child. Let’s look at a trivial example and then later build on it.

Here’s a definition of a parent class:

class Parent
def say_hello
puts "Hello from #{self}"
end
end

p = Parent.new
p.say_hello

Output: Hello from #<Parent:0x0a40c4>

and a child class that inherits from it:

# Subclass the parent...
class Child < Parent
end
c = Child.new
c.say_hello

Output: Hello from #<Child:0x0a3d68>

The parent class defines a single instance method, say_hello. We call it by creating a new instance of the class and store a reference to that instance in the variable p. We then create a subclass using class Child < Parent. The < notation means we’re creating a subclass of the thing on the right; the fact that we use less-than presumably signals that the child class is supposed to be a specialization of the parent. Note that the child class defines no methods, but when we create an instance of it, we can call say_hello. That’s because the child inherits all the methods of its parent. Note also that when we output the value of self — the current object - it shows that we’re in an instance of class Child, even though the method we’re running is defined in the parent.

Generators<ref name = generators/>

Source code generation is the act of generating source code based on an ontological model such as a template and is accomplished with a programming tool such as a template processor or an IDE. These tools allow the generation of source code through any of various means. A macro processor, such as the C preprocessor, which replaces patterns in source code according to relatively simple rules, is a simple form of source code generator. Parser generators (lex & yacc, antlr, rats!, treetop, pyPEG, and so on.) are probably the best-known examples of application generators. Other examples include wizards that one can find in Integrated Development Environments (to design and generate code of user interfaces, for example), tools that generate classes from UML class diagrams, generators of database schemas, report generators, etc.

Software architectures

Software architectures are large-grain software frameworks. In contrast with source code components which are often black-boxes, software architecture are designed as grey-boxes: they are intended to be extended and provide specific extension points for this. We have a lot of reusable frameworks nowadays. Probably the most common are web frameworks (Ruby on Rails, django, ASP.net, ...), integrated development environment (IDE, Eclipse is worth mentioning due to its architecture), service oriented architectures (SOA), and so on.

Design and code scavenging

Design and code scavenging is simply a form of "find, copy-paste, adapt". The well-known design patterns provide an organized form of design scavenging, by providing catalogs for applying such kind of reuse. Even if invented in the context of the object-oriented programming, design patterns had a great impact far beyond that programming paradigm.

Code scavenging is less organized as few such catalogs exists. Every day however, the web gives users better ways to apply reuse techniques such as google code search, github's gist, pastie, and so on.

Transformational systems

Transformational systems are the holy grail of computer science, nothing less! In that paradigm, software developers actually describe the behavior of the software using a high-level specification language (related to VHLL described before). In a second phase, the specifications are transformed in order to produce an executable system. The transformations are meant to enhance efficiency without changing the semantics.

Transformational systems emphasizes the what instead of the how. They actually bet on the concision of declarative statements over procedural ones to achieve effective reuse. While general purpose transformation systems remain mostly research topics, notable results have been achieved in some specific domains: relational systems come with effective query optimizers, some rapid prototyping approaches using transformations from high-level descriptions down to code, etc.

Very High Level Languages (VHLL)

Very High Level Languages, also known as executable specification languages, are languages with very high level of abstraction. They are somewhat difficult to capture precisely and may lead to software reuse that is very specific to specialized domains. However, the recent advent of Domain Specific Languages (DSLs) and good support for them in dynamic languages (ruby, python, clojure, ...) and can be seen as promoting and helping building VHLLs.

Best practices <ref name = best_practices />

Here are some of the best practices to be followed to make sure that the code that is being written is reusable.

  • The first consideration is to write code that uses a consistent naming convention, that is formatted properly, and that contains useful comments.
  • Examine the code to make sure that all the procedures have a single, specific purpose. Make sure that the procedure can be describedin a short, plain sentence. For example, "This procedure accept two numbers and calculates the product of those two numbers". If a procedure can not be described simply and clearly in a sentence, then it probably does too many things. Break down complicated procedures into smaller ones that do one thing each. Procedures should contain only code that clearly belongs together.
  • Avoid making specific reference to named application objects.
  • Try to minimize the number of arguments in a procedure and pass in only what is actually required by the procedure. In addition, make sure the procedures use all the arguments passed to them.
  • Group related procedures and the constants they use together in the same module, and where appropriate, consider grouping related procedures together in a class module with a clearly defined interface.
  • Keep procedures in standard modules and not in modules behind forms or documents. The code in form modules should be only the code that is tied directly to the form itself and the code required for calling general procedures stored in standard modules.
  • Communicate between procedures by passing data as arguments to the procedures. Persist data by writing it to disk. Avoid using a procedure to write to a global variable so another procedure can read data from that global variable. Avoid communicating with another procedure by passing data out of the application, for example, using one procedure to write data to a disk file so another procedure can read that data.

Advantages <ref name = history_pros_cons/>

  • Efficiency - Software reuse increases the software productivity and decreases the time required for the development of a software by reducing the time spent in designing or in coding
  • Standardization - By using the technique of software reuse, a company can improve software system interoperability and needs less people for software development. This provides a competitive advantage for the company and helps to produce better quality software and standardized software.
  • Consistency - Reuse of UI widgets in MacOS and Win32 leads to common “look-and-feel” between applications
  • Debugging -
  • Reliability - Systems that incorporate a high level of reusable components are more reliable and more easily constructed. Reused design/code is often tested design/code.
  • Profit! - Software reuse technique helps the company to reduce the costs involved in software development and maintenance.
  • Reduced Risk - Software reuse also reduces the risk involved in software development process.
  • Component Market - Reuse can lead to a market for component software. Real-world examples: ActiveX components, Hypercard stacks, Java packages, even software tools, such as xerces and xalan from xml.apache.org (they are often included in other software systems)

Trade-offs for code reuse at various levels of components <ref name=trade_offs/>

Different types of application code require varying levels of investment to achieve successful reuse

  • Reusable GUI objects reduce development time and improve quality and consistency but provide only modest payback in terms of overall application development costs.
  • Server-side components that constitute reusable business logic can provide significant payback but require extensive up-front analysis and design. They also require an architectural foundation but may experience a short shelf life.
  • Infrastructure components and services frameworks are generic services for transactions, messaging, security, and database connectivity. They eliminate the need to repeatedly build infrastructure that all applications use, but require extensive analysis and design, and complex programming. These standards-based components can often be purchased off-the-shelf.
  • High-level patterns allow organizations to achieve design reuse and identify components with high reuse potential, but developers must build or acquire the components.
  • Packaged applications provide the only guaranteed form of reuse, letting user companies acquire functionality for significantly less than the cost of building it themselves. However, these applications may not offer the exact functionality an organization needs; the subsequent customization that's required will add to the cost.

Practical problems <ref name = history_pros_cons/>

Although software reuse provides many benefits for the developers, there are some disadvantages.

Disadvantages for developers who reuse the code

  • Mismatch - Reused code or design may not completely match the situation, in that case, reusing the code may incur additional time and effort.
  • Non-functional characteristics of code may not match the situation - Consider a database that can scale to 10,000s of items, but you need it to scale to 100,000s of items.
  • Expense - Some components may be too expensive for the project’s budget. For instance, SGML (a precursor to HTML and XML) tools sell for 5000 dollars a license!

Disadvantages for developers who develop reusable code

  • Building reusable objects requires extensive analysis and design. The developer needs to understand and take into consideration all the generalities while coding the reusable module.
  • The developer needs to invest extra time in testing and quality assurance, optimization, and documentation. All this takes time and labor, which increases the cost of the code.
  • IT departments must also add to the payback equation the cost of tools to support reuse, such as version control and repositories.
  • The cost of administering an ongoing reuse program must be considered.

With all these elements, it becomes apparent that reuse doesn't come cheap.

Conclusion

The only way you can avoid code depreciation is through reuse but you need to be disciplined and follow a strict process. Reuse enables you to do more with less.

See also

References

<references>

<ref name = techniques> http://www.revision-zero.org/reuse</ref> <ref name = definition_software_reuse> http://www.biglever.com/papers/Krueger_AcmReuseSurvey.pdf </ref> <ref name = history_pros_cons> http://www.cs.colorado.edu/~kena/classes/3308/f04/lectures/lecture10.pdf </ref> <ref name = wiki_code_reuse> http://en.wikipedia.org/wiki/Code_reuse </ref> <ref name = trade_offs> http://www.informationweek.com/708/08iuhid.htm </ref> <ref name = best_practices> http://msdn.microsoft.com/en-us/library/office/aa189298%28v=office.10%29 </ref> <ref name = Object_orinetation> http://en.wikipedia.org/wiki/Object-oriented_programming </ref> <ref name = generators> http://en.wikipedia.org/wiki/Generative_programming </ref>

</references>