Inversion of control

In software engineering, inversion of control (IoC) is a design principle in which custom-written portions of a computer program receive the flow of control from a generic framework. A software architecture with this design inverts control as compared to traditional procedural programming: in traditional programming, the custom code that expresses the purpose of the program calls into reusable libraries to take care of generic tasks, but with inversion of control, it is the framework that calls into the custom, or task-specific, code.

Inversion of control is used to increase modularity of the program and make it extensible,[1] and has applications in object-oriented programming and other programming paradigms. The term was popularized by Robert C. Martin and Martin Fowler.

The term is related to, but different from, the dependency inversion principle, which concerns itself with decoupling dependencies between high-level and low-level layers through shared abstractions.

Overview

As an example, with traditional programming, the main function of an application might make function calls into a menu library to display a list of available commands and query the user to select one.[2] The library thus would return the chosen option as the value of the function call, and the main function uses this value to execute the associated command. This style was common in text based interfaces. For example, an email client may show a screen with commands to load new mails, answer the current mail, start a new mail, etc., and the program execution would block until the user presses a key to select a command.

With inversion of control, on the other hand, the program would be written using a software framework that knows common behavioral and graphical elements, such as windowing systems, menus, controlling the mouse, and so on. The custom code "fills in the blanks" for the framework, such as supplying a table of menu items and registering a code subroutine for each item, but it is the framework that monitors the user's actions and invokes the subroutine when a menu item is selected. In the mail client example, the framework could follow both the keyboard and mouse inputs and call the command invoked by the user by either means, and at the same time monitor the network interface to find out if new messages arrive and refresh the screen when some network activity is detected. The same framework could be used as the skeleton for a spreadsheet program or a text editor. Conversely, the framework knows nothing about Web browsers, spreadsheets or text editors; implementing their functionality takes custom code.

Inversion of control carries the strong connotation that the reusable code and the problem-specific code are developed independently even though they operate together in an application. Software frameworks, callbacks, schedulers, event loops and dependency injection are examples of design patterns that follow the inversion of control principle, although the term is most commonly used in the context of object-oriented programming.

Inversion of control serves the following design purposes:

Inversion of control is sometimes facetiously referred to as the "Hollywood Principle: Don't call us, we'll call you".

Background

Inversion of control is not a new term in computer science. Martin Fowler traces the etymology of the phrase back to 1988.[3] Dependency injection is a specific type of IoC using contextualized lookup.[2] A service locator such as the Java Naming and Directory Interface (JNDI) is similar. In an article by Loek Bergman,[4] it is presented as an architectural principle.

In an article by Robert C. Martin,[5] the dependency inversion principle and abstraction by layering come together. His reason to use the term "inversion" is in comparison with traditional software development methods. He describes the uncoupling of services by the abstraction of layers when he is talking about dependency inversion. The principle is used to find out where system borders are in the design of the abstraction layers.

Description

In traditional programming, the flow of the business logic is determined by objects that are statically bound to one another. With inversion of control, the flow depends on the object graph that is built up during program execution. Such a dynamic flow is made possible by object interactions being defined through abstractions. This run-time binding is achieved by mechanisms such as dependency injection or a service locator. In IoC, the code could also be linked statically during compilation, but finding the code to execute by reading its description from external configuration instead of with a direct reference in the code itself.

In dependency injection, a dependent object or module is coupled to the object it needs at run time. Which particular object will satisfy the dependency during program execution typically cannot be known at compile time using static analysis. While described in terms of object interaction here, the principle can apply to other programming methodologies besides object-oriented programming.

In order for the running program to bind objects to one another, the objects must possess compatible interfaces. For example, class A may delegate behavior to interface I which is implemented by class B; the program instantiates A and B, and then injects B into A.

Implementation techniques

In object-oriented programming, there are several basic techniques to implement inversion of control. These are:

In an original article by Martin Fowler,[6] the first three different techniques are discussed. In a description about inversion of control types,[7] the last one is mentioned. Often the contextualized lookup will be accomplished using a service locator.

More important than the applied technique, however, is the optimization of the purposes.

Examples

public class ServerFacade {
   public <K, V> V respondToRequest(K request) {
      if (businessLayer.validateRequest(request)) {
         DAO.getData(request);
         return Aspect.convertData(request);
      }
      return null;
   }
}

Most frameworks such as .NET or Enterprise JavaBeans display this pattern.

This basic outline in Java gives an example of code following the IoC methodology. It is important, however, that in the ServerFacade a lot of assumptions are made about the data returned by the data access object (DAO).

Although all these assumptions might be valid at some time, they couple the implementation of the ServerFacade to the DAO implementation. Designing the application in the manner of inversion of control would hand over the control completely to the DAO object. The code would then become

public class ServerFacade {
   public <K, V> V respondToRequest(K request, DAO dao) {
      return dao.getData(request);
   }
}

The example shows that the way the method respondToRequest is constructed determines if IoC is used. It is the way that parameters are used that define IoC. This resembles the message-passing style that some object-oriented programming languages use.

See also

References

  1. Ralph E. Johnson & Brian Foote (June–July 1988). "Designing Reusable Classes". Journal of Object-Oriented Programming, Volume 1, Number 2. Department of Computer Science University of Illinois at Urbana-Champaign. pp. 22–35. Retrieved 29 April 2014.
  2. 1 2 Dependency Injection.
  3. Inversion of Control on Martin Fowler's Bliki
  4. Inside Architecture: write once, run anywhere by Loek Bergman
  5. The Dependency Inversion principle by Robert C. Martin
  6. Inversion of Control Containers and the Dependency Injection Pattern by Martin Fowler
  7. IoC Types

External links

Wikimedia Commons has media related to Inversion of control.


This article is issued from Wikipedia - version of the Friday, April 15, 2016. The text is available under the Creative Commons Attribution/Share Alike but additional terms may apply for the media files.