JAL Computing

C++COMProgramming .NET Mac Palm CPP/CLI Hobbies

 

Home
Up

Chapter 10 "Indirection and Loose Coupling"

Some would argue that indirection is a basic principle of OOP (object oriented programming) and a basic tenant of Software Engineering 101. The concept of a class that encapsulates or hides the actual implementation details can be considered an example of the use of indirection. In this example, the use of indirection adds flexibility and eases code maintenance. A closely related, but poorly defined topic in software engineering, is the concept of loose coupling

The concept of indirection is pervasive in computer science and impacts design not only of software, but hardware and network communication. In this chapter I am going to take leave of my self imposed constraint of a "Twisted Look at OOP" and examine the concept of indirection as useful general abstraction.

A Few Definitions

According to "Webster's Seventh New Collegiate Dictionary" indirection is:

bullet1a : lack of straightforwardness and openness : DECEITFULNESS
bullet2a : indirect action or procedure

Hopefully, it is the second definition that best describes indirection in computer science! If an "indirect action or procedure" sounds like a circular definition, then we can rely on Webster's definition of indirect which is "deviating from a direct line or course : ROUNDABOUT." So indirection is an action or procedure that deviates from a direct course. However, in OOP that indirection is through a software module or class. In fact, the distinguishing characteristic of the use of indirection in computer science is that the path deviates through an intermediary.

So for the purposes of this discussion, we will define indirection as "taking a path that is not direct and one that passes through an intermediary." We often speak of levels of indirection so that the path can be through one or more intermediaries. In the remainder of this chapter we will investigate this general abstraction as it applies to the computer sciences.

Here is a graphical view of a single level of indirection.

What's this?

Indirection is often achieved through abstraction and encapsulation, but the terms are not synonymous. Abstraction refers to the process of decomposing a problem or structure into simpler problems or pieces that represent the essence of a thing or idea. Encapsulation refers to the separation of the public contract, the interface, from the actual implementation. In the following examples of indirection, look for the use of abstraction or encapsulation!

Finally, indirection may lead to loose coupling. Unfortunately, a rigorous definition of loose coupling is hard to find. Again from Webster's we have:

coupling

bullet1 : the act of bringing or coming together : PAIRING

loose 

bullet1a : not rigidly fastened or securely attached
bullet2a : free from a state of confinement, restraint, or obligation

So we can say that two processes are loosely coupled when the pairing is not rigid. In other words, loosely coupled processes are flexible. Specifically, we often mean that processes are loosely coupled when we can change the implementation details without disrupting the interaction. A generic interface between two processes such as messaging encourages such loose coupling. So we can also say that two processes are loosely coupled when the pairing is not dependent on the implementation details of each process.

Examples of Indirection

Here is a limited list of examples of the use of indirection. This chapter is most definitely a work in progress and is meant to stimulate thought and discussion. Contributions are welcome!

bulletClass as Indirection
bulletData as Indirection
bulletAddress as Indirection
bulletPhysical Separation as Indirection
bulletPointer to a Pointer as Indirection
bulletN-Tiered Applications as Indirection

Class as Indirection

We have already touched upon the use of a class to encapsulate or hide implementation details as an example of indirection. A concrete example is the use of an array to store data internally. The caller of the class method is not aware of how the data is stored internally. The class can be rewritten to store the data in a dictionary and this would not affect the public view of the class. In this example, indirection is accomplished through encapsulation or information hiding. Another concrete example of indirection is the wrapping of a data source in a class. The data source could be a local file or a remote database query. Again, since the class encapsulates or hides the implementation details, the class can be redesigned without affecting the caller.

Data as Indirection

Many database APIs hide the data source by converting data from different sources into a common data format such as a "recordset." This is an example of indirection using abstraction. For instance, if database specific calls are wrapped into a single class, then the class can return generic objects that represent the data. By programming to a database neutral API, a complex project can isolate the general solution from a specific database provider. All that is required to migrate the application to a new database provider is a new database specific class wrapper that maps generic calls to database specific calls, generating generic data objects from database specific return values.

Another example of "Data as Indirection" is XML formatted data. Again, an intermediary sits between the data producer and the data consumer. This intermediary converts uniquely formatted data from a specific data source to a general XML format for consumption. The consumer is not aware of the format of the original data, but can expect the data to be returned as XML.

Address as Indirection

The use of an intermediary to lookup an address is an example of indirection. A concrete and powerful example is the use of a name server on the Internet. Instead of navigating the Internet with hard coded IP addresses such as http://192.168.1.1 (this private IP address does not work mind you), the Internet can be navigating with a name such as http://www.geocities.com/jeff_louie. According to the Internet Protocol "A name indicates what we seek. An address indicates where it is. A route indicates how to get there." The name server is the intermediary that returns the address from the name query. The power of address indirection is evident anytime a site is moved to a new IP address. The abstraction of address indirection adds flexibility at the cost of complexity, the DNS (Domain Name Service). Address as indirection is accomplished without abstraction.

Another example of address indirection is the use of mail forwarding. In this example an intermediary computer redirects mail say from [email protected] to [email protected]. Again this indirection is accomplished without abstraction or encapsulation. Finally, in a world of constantly changing ISP (Internet Service Providers) an intermediary can be used to map a third party Internet mail service to your current mailbox. As you change mail boxes, the intermediary third party mail service can be configured to forward your mail the your new mailbox.

Interestingly, address as indirection looks very similar to pointer to a pointer as indirection.

Physical Separation as Indirection

In a sense, address indirection may lead to physical separation of the producer and consumer. Still, it is useful to think of physical separation itself as a form of indirection. On a micro scale a consumer and producer can both be part of a single application such as an local file based application. Next, the consumer and producer may be on separate processes on the same server. (An example would be a GUI front end and a database engine.) On a physical scale, the consumer and producer can be on separate devices on the same network. (An example would be an XWindows GUI and a remote XWindows provider.) Next, the provider and consumer can be on a different networks. Finally, the producer could be part of a distributed server farm.

Mechanically, data can be stored on a single hard drive or spread over multiple drives on the same machine (RAID) or over multiple devices on a network. In this example, physical indirection may add reliability (RAID Level 1) at the cost of complexity. This is an example of indirection using abstraction and encapsulation.  The user of the virtual abstract drive is not concerned about the implementation details.

Pointer to a Pointer as Indirection

The classic example of indirection in programming is the pointer. Instead of passing the actual data, you can pass the address of the data. This is considered single indirection. Passing a pointer to data is more efficient than passing a copy of a large data structure to a method. Again, this type of indirection does not use abstraction.

A more obtuse and powerful use of indirection is double indirection in which you pass the address of a master pointer with a pointer or so called handle (a pointer to a pointer **p). The master pointer in turn contains the current address of the data! Again this indirection hides the actual memory address of the data. Due to the added level of indirection it is possible to compact memory (move the data or code between segments of memory) behind the scenes and then update the so called master pointer. Double indirection is central to many memory management schemes that use "relocatable" memory.

More information on double indirection is available at http://www.mindfiresolutions.com/download/Mac=Memory%20Manager.pdf  

Interestingly, pointer to a pointer as indirection looks very similar to address as indirection.

N-Tiered Applications as Indirection

This one is pretty self explanatory. In a N-Tiered application requests are processed through a linear chain of intermediaries. In a three tiered application the middle tier can encapsulate the business rules and the back end tier can provide the database intelligence. This separation of business rules and database intelligence from the GUI client protects the integrity of the data and provides a central means for enforcing the business rules.  By coding business rules in a middle tier, such an architecture can support multiple GUI clients. Any change in the business rules will automatically be enforced on all GUI clients.

Advantages of Indirection

As demonstrated by the previous examples, indirection is a powerful abstraction that increases flexibility and simplifies maintenance. Indirection may lead to loose coupling.

Disadvantages of Indirection

Indirection adds complexity and is not as efficient as taking the most direct path. Indirection may not be necessary when writing a small stand alone project. The user of indirection should be able to articulate the benefits of the added level of complexity.

Indirection often is accomplished using abstraction or encapsulation, but the terms are not synonymous. As demonstrated above, not all examples of indirection involve abstraction or encapsulation. Indirection is closely related to the concept of loose coupling.

In this chapter, we defined indirection as "taking a path that is not direct and one that passes through an intermediary." Indirection is a basic principle of OOP and a well known abstraction used throughout the computer sciences. Like a catchy song that won't leave your head, you may start to see indirection everywhere you look! My apologies.

Have fun,
Jeff

All Rights Reserved Jeff Louie 2003

 
Send mail to [email protected] with questions or comments about this web site. Copyright © 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 © 
Last modified: 08/04/09
Hosted by www.Geocities.ws

1