CSC/ECE 517 Fall 2009/wiki3 5 rm: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
Line 41: Line 41:
         m_worker=w;
         m_worker=w;
     }
     }
     public void manage() {
     public void manage() {
         m_worker.work();
         m_worker.work();

Revision as of 17:49, 18 November 2009

Dependency Inversion policy

Introduction

The Dependency Inversion Principle has been proposed by Robert C. Martin. It states that:

"High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions."

The principle is reverse the conventional philosophy of high level functions in softwares need to depend on the low level functions. The principle states that high level or low level modules should not depend upon each other, instead they should depend upon abstractions. Further it also states that these abstractions should not depend on the details and inversely the details should depend on the abstractions. According to this principle the way of designing a class structure is to start from high level modules to the low level modules:

High Level Classes → Abstraction Layer → Low Level Classes

Overview

The Dependency Inversion Principle is defined as follows:

  1. High-level modules should not depend upon low-level modules. Both should depend upon abstractions.
  2. Abstractions should not depend upon details. Details should depend upon abstractions.

The problem with the conventional design architecture is that the higher level components depends on the lower level components. This can be understood from the diagram below.

Figure 1: Higher-level components depend upon lower-level components

From the above diagram we see that the component A depends on component B, which in turn depends on component C. These dependencies make the higher level modules or components more complex and inflexible. This also leads to tight coupling of higher and lower level components. Thus reducing the over all flexibility of the system.

The primary motive of the dependency inversion principle is to decouple the high level components from their dependency on the low level components of the system. This can be obtained by creating interfaces as a part of the higher level component package which define the components for the extra functionality required. This protects the component from depending on any specific implementation of the provided interface/functionality. Thus making the given function more portable. The above example can be restructured as follows

Figure 2: Relationship diagram

As one can see in the above figure the component B doesn't depend on A but rather depends on the interface that is also used by A. The same relationship is additionally shown between components B and C. Take special note that the interfaces are packaged together with the higher-level components and are defined in terms of the higher-level component’s needs, not the lower-level component’s behavior. It is this association of the interface with the client component which logically inverts the conventional dependency flow.

Example of Dependency inversion principle

// Dependency Inversion Principle - Bad example
class Worker {
    public void work() {
    // ....working
    }
}
class Manager {
    Worker m_worker;
    public void setWorker(Worker w) {
        m_worker=w;
    }
    public void manage() {
        m_worker.work();
    }
}
class SuperWorker {
    public void work() {
    //.... working much more
    }
}


The code shown below implements the code above using Dependency Inversion principle.This helps us in solving the following problems.

  1. Manager class should not be changed.
  2. Minimized risk to affect old funtionallity present in Manager class.
  3. No need to redone the unit testing for Manager class.

// Dependency Inversion Principle - Good example interface IWorker { public void work(); }

class Worker implements IWorker{ public void work() { // ....working } }

class SuperWorker implements IWorker{ public void work() { //.... working much more } }

class Manager { IWorker m_worker;

public void setWorker(IWorker w) { m_worker=w; }

public void manage() { m_worker.work(); } }

A design pattern based on dependency inversion policy (Template design pattern)

The Template Design pattern implements the Dependency Inversion Principle by setting up the outline or skeleton of an algorithm, leaving the details to be implemented by the classes or modules implementing it. This way, the sub classes will be getting there information from the abstract classes. Further these abstract classes are not dependent on the details while the vice versa is true. The UML diagram below gives you better understanding of the Template design pattern. There are method calls to operation1() and operation2(). The definition of these methods are defined in the subclass which override them.

Figure 3: Template Design Pattern

Conclusion

This principle is applied to make sure that the high level classes are not directly dependent on the low level classes, they are doing that using either by interfaces or abstract classes.In that case the creation of new low level objects inside the high level classes(if necessary) can not be done using the operator new. Instead, some of the Creational design patterns can be used, such as Factory Method, Abstract Factory, Prototype. Of course, using this principle implies an increased effort and a more complex code, but more flexible. This principle can not be applied for every class or every module. If we have a class functionality that is more likely to remain unchanged in the future there is not need to apply this principle.When a component does not depend on lower level components directly but only through abstractions this component is mobile that is, the component is reusable in many different contexts.

References

[1] http://www.objectmentor.com/resources/articles/dip.pdf
[2] http://www.ctrl-shift-b.com/2008/12/examining-dependency-inversion.html Amazing article lots of stuff
[3] http://blogs.imeta.co.uk/jyoung/archive/2008/12/17/540.aspx----pics in here as well
[4] http://en.wikipedia.org/wiki/Dependency_inversion_principle
[5] http://www.lostechies.com/blogs/gabrielschenker/archive/2009/01/30/the-dependency-inversion-principle.aspx
[6] http://www.oodesign.com/dependency-inversion-principle.html
[7] http://www.eventhelix.com/realtimemantra/Object_Oriented/dependency_inversion_principle.htm
[8] http://davidhayden.com/blog/dave/archive/2005/06/10/1261.aspx
[9] http://doodleproject.sourceforge.net/articles/2001/dependencyInversionPrinciple.html
[10] http://stackoverflow.com/questions/62539/what-is-the-dependency-inversion-principle-and-why-is-it-important
[11] http://www.surfscranton.com/architecture/DIPandOCP/img0.html
[12] http://iface.wordpress.com/2006/03/16/dependency-inversion-principle-and-interface/
[13] http://www.exciton.cs.rice.edu/JavaResources/DesignPatterns/TemplatePattern.htm