Component Based Software Engineering

A good software engineering paradigm is to utilize what I term "components." In a generic sense, a component is a self-contained part, or unit, used within a larger construct. There is perhaps no single, precise definition of the term, as it depends upon usage. In a simple sense, a function in a programming language is a component, as it is a single, self-contained unit of code used for some purpose. However, as I use the term, it refers to some larger unit that consists of functions and/or data, a step up, perhaps, from the simple function.

There are many manifestations of the "component" depending upon the language being used. Examples include such things as the "plugin," as it is referred to in jQuery, a JavaScript based extension known to almost all web programmers. Another example would be the C++ class. In each case the entity, i.e., the component, is a unit of code containing methods and data that is used for a specific purpose. Here, I discuss the concept of component as a construct in JavaScript, but first a bit of background.

In Theory

The most important characteristic of a component is that it should be "opaque," that is, the user cannot see into it or access its internal state, and the component makes no reference to anything external to itself. This characteristic is termed "encapsulation." It ensures that, if the component is well-formed, it should always work correctly and in the same way. Except, of course, when GIGO occurs: "Garbage In, Garbage Out." One must still insure that any parameters passed into the object are correct.

Here I would like to discuss components as they might be implemented in JavaScript. Two constructs of JavaScript that are indispensible in the implementation of components in that language are the anonymous function and the closure. The anonymous function is a fairly obvious concept, a function without a name. For example, the following code makes use of an anonymous function:

		var twice = function( x ) { return 2 * x; }
	

This assigns an anonymous function (no name) to a variable named twice. The function can then be invoked via the variable name. Naturally, in the following code fragment, the variable x will have the value 20:

		var x = twice( 10 );
	

Closure is a bit more difficult to explain, but it is central to the language, and involves the notion of "scope." Scope refers, in a sense, to the life span of an object. It becomes "alive" when it is declared or called; it ceases to exist when the containing block ceases to exists, or when it returns. This is central to most procedural programming languages. Thus, in a language such as C, a variable declared in a function exists only within the function. While the function is executing the variable exists. Once the function terminates, or returns to its caller, the function goes out of scope, and its internal state, including the declared variable, no longer exist. In other words, a variable declared within a function cannot be referenced outside that function.

This seems like an obvious state of affairs, and is generally true. Except in a language like JavaScript, where it does not necessarily hold true, and the reason for it is the concept of "closure." When a function is created JavaScript maintains its context, so it has access to all functions and data that were visible to it when created.

Consider the following code:

		var getPi = function( ) {
			var pi = 3.141592;
			var valueOfPi = function( ) {
				return pi;
			};
			return valueOfPi;
		};

		var x = getPi( );
		alert(  'pi = ' + x( ) );
	

The variable pi would appear to have scope only within the function getPi, which, once called, goes out of scope. And yet, all is well, because of closures. The context of function valueOfPi is preserved, so that when x() is called, the value of pi continues to exist. This is the essence of what is known as a closure.

In Practice

Encapsulation and componentization are easily implemented in JavaScript by taking advantage of anonymous functions, local variables, and closure. The following template illustrates the idea.

	var myComponent = ( function( ) {

		var someData = '1234';

		var do_someFunc = function( args ) {
		};

			'
			.
			.

		return {
			someFunc : function( args ) { do_someFunc( args ); }
		};

	} )( );
	

If this code were placed in a file and included via a <script> tag, there would exist a global variable named myComponent whose properties are functions that access the code with local scope. Once included one can then make calls as in

		myComponent.someFunc( 'xyz' );
	

The syntax of the definition may seem a bit strange at first, but placing the function definition within parentheses followed by an argument list (possibly empty) immediately invokes the function. The returned value, an object whose properties are all methods, is saved in the variable myComponent for later use.

This same template can be used to create jQuery plugins. A plugin is simply a functional extension to jQuery, which is stored in the jQuery member object named fn. Here is the same template as a jQuery plugin:

	( function( $ ) {

		var someData = '1234';

		var do_someFunc = function( args ) {
		};

			'
			.
			.

		$.fn.myComponent = function( args ) {
				.
				.
				.
			return this;
		};

	} )( jQuery );
	

Then, in your script you can add an instance of the plugin to any jQuery object by coding something such as this:

		var mC = $( '#container' ).myComponent( someargs );
	

Note that myComponent returns a reference to itself, which can be saved in a program variable for later invocation under program control. Depending upon what the plugin does, this may or may not be necessary.

There are other code patterns that can accomplish the same goals outlined here. But, I have always considered these the most elegant, and have used them successfully many times. Check my components page for examples. Hope that helps!