CSC/ECE 517 Fall 2009/wiki2 7 ov

From Expertiza_Wiki
Jump to navigation Jump to search

Survey of Language Features for Code Reuse

Direct inclusion

Code can be reused by simply storing it in a defined location and allowing a compiler or preprocessor to insert a copy of the code whenever it is referenced. This is the simplest form of code reuse and is present in many languages.

Assembly Language - Macros

Many assemblers have support for macros. A macro is a block of code that can be called from any location in the program. A macro can contain any number of instructions and is given a unique name. Some assemblers also support passing various parameters to a macro which can be inserted into the code block contained in the macro.

Within a program the assembler replaces all references to the macro's name with the block of code that the macro represents. Essentially macros allow the programmer to give a chunk of code a name and then use it multiple times within a program or even in many programs.

C/C++ - Includes

The languages C and C++ had a directive named #include which instructs the compiler to insert the contents of a file into the current source file. Typically a program will use this feature to allow certain functions and macros to be used within multiple source files or in multiple programs.

Used in this way, the prototype for a function would be placed in a file and the file that includes the source code to the function and any file that contains source code using the function will use #include to reference the file containing the function prototype. This allows the compiler to reference the source code to the function wherever it happens to be called.

Ruby - Mixins and Modules

Ruby has several different features that can be used individually or together to allow a programmer to reuse sections of code. One such feature is known as a module. A module contains a block of code and places it underneath a defined name (or namespace). Variables, classes, and functions within a module can be used by referencing the module name followed by a . and then the name of the item in the module.

For instance, if there is a module named Square which contains a function called draw it can be called by writing:

Square.draw()

If a module is referenced within a class definition that module is often referred to as a mixin. Any functions or variables that are defined in the module can be used within the class just as if it was defined directly within the class. For instance a module may define methods that are used in several different classes. Each class that needs one of the methods in the module can include the module as a mixin.

A module can be referenced in a class or program by using either the load or require statements. If the load statement is used the module will be coped into the location of the statement much like an Assembly language macro or a C or C++ include.

If the require statement is used then only one copy of the module is loaded into memory. If the module is changed during runtime all parts of the program using that module see the change immediately since they are all using the same chunk of code in memory.

Because of this property modules in Ruby can act like a direct inclusion or a collection of classes.

Collections of Classes

In some object oriented languages code can be reused by grouping certain classes together under a single name. These collections are known by different names in different languages but they all typically provide a way to reference a particular class within a collection even if a class with the same name may be found in a different collection.

Java - Packages

Java allows classes to be grouped into a collection known as a package. A program can then reference the package and use the classes defined within it or reference a particular class in a package.

Each package is given a unique name and each class in a package can be referenced by giving the name of the package followed by the name of the class like this:

java.util.Date somedate = new java.util.Date();

.NET - Components and Namespaces

Microsoft's .NET family of languages allows a class or a group of classes to be compiled into a component. Components typically need to be compiled into a binary DLL containing CLR code.

Programs can use a component by adding a reference the DLL containing the component's code . Classes contained within a component can then be used just as if the classes were defined directly in the program.

The .NET languages also support a feature called namespaces which allows classes to be referenced by a fully qualified name much like Ruby's modules or Java packages. For more complicated designs, a namespace can be nested within another namespace like this:

namespace Shape
{
	namespace TwoDimensional
	{
		public class Square
		{
		}

		public class Circle
		{
		}
	}

	namespace ThreeDimensional
	{
		public class Cube
		{
		}
	}
}

In this case the class Circle could be referenced from another program by placing the Shape namespace into a component and calling:

Shape.TwoDimensional.Circle myCircle = new Shape.TwoDimensional.Circle();

Comparison

Languages that use a form of direct inclusion often make it very easy to reuse any particular block of code in multiple applications or even within the same application. The principal is a very simple one and is usually quite easy to implement in any given language. However, most forms of direct inclusion do not provide a way to avoid conflicts when multiple variables, functions, routines, classes, or methods share the same name.

Languages that group classes into self-contained collections provide a fairly elegant way to avoid name collisions because each class can be referenced using a fully qualified name that includes the name of the collection it is in. They may not be quite as simple or as easy to use as most forms of direct inclusion but the ability to avoid namespace collisions is often worth it. It is also often easier to determine which collection/package/component a class belongs to than it is to determine which included file contains the class in a direct inclusion system which can aid in debugging and troubleshooting problems.

References