Spring框架核心思想IOC(控制反转)和DI(依赖注入)的本质

定义一个接口

public interface Person {
  void sayHello(); 
}

 

第一个实现类:

public class Chinese implements Person {
  public void sayHello() {
    System.out.println("您好 !");//
  }
}

 

  

第二个实现类:
public class American implements Person {
  public void sayHello() {
    System.out.println("How do you do .");
  }
}

传统设计模式:调用者自己创建被调用者的实例
//这里的User充当调用者,实例对象C和A充当被调用者的实例
public class User{
  Person C = new Chinese();
  Person A = new American();
  public sayHello(){
    C.sayHello();
    A.sayHello();
  }
}

 

控制反转:注意这个类与传统设计的区别:该类调用Person子类的方法,传统设计在本类中创造实例,而在此类里并没有创造实例
public class User {
  Person p;
  public Person getP() {
    return p;
}

//使用setter注入
public void setP(Person p) {
  this.p = p;
}

//调用person子类重写的sayHello方法,这里的p并没有实例化
public void function(){
  p.sayHello();
}

 

外部容器:这里有容器来创建被调用实例,然后通过setP()方法注入

public class Container{

  public static User getBean(){

    Person p=new Chinese();//p充当别调用者实例对象

    User user = new User();//user调用者实例对象

    //由容器‘注入’实例

    user.setP(p);

    return user;
  }
}


测试类:

public class Test{

  public static void main(String[] args){

    User user = Container.getBean();

    user.function();
  }
}

//后台输出‘您好’

通过这个例子应该看懂了控制反转,和依赖注入了吧,这个是不是与传统设计相反了。

 

相关知识

依赖和耦合(Dependency and Coupling)

如果模块A调用模块B提供的方法,或访问模块B中的某些数据成员(当然,在面向对象开发中一般不提倡这样做),我们就认为模块A依赖于模块B,模块A和模块B之间发生了耦合。

  那么,依赖对于我们来说究竟是好事还是坏事呢?

  由于人类的理解力有限,大多数人难以理解和把握过于复杂的系统。把软件系统划分成多个模块,可以有效控制模块的复杂度,使每个模块都易于理解和维护。但在这种情况下,模块之间就必须以某种方式交换信息,也就是必然要发生某种耦合关系。如果某个模块和其它模块没有任何关联(哪怕只是潜在的或隐含的依赖关系),我们就几乎可以断定,该模块不属于此软件系统,应该从系统中剔除。如果所有模块之间都没有任何耦合关系,其结果必然是:整个软件不过是多个互不相干的系统的简单堆积,对每个系统而言,所有功能还是要在一个模块中实现,这等于没有做任何模块的分解。

  因此,模块之间必定会有这样或那样的依赖关系,永远不要幻想消除所有依赖。但是,过强的耦合关系(如一个模块的变化会造成一个或多个其他模块也同时发生变化的依赖关系)会对软件系统的质量造成很大的危害。特别是当需求发生变化时,代码的维护成本将非常高。所以,我们必须想尽办法来控制和消解不必要的耦合,特别是那种会导致其它模块发生不可控变化的依赖关系。依赖倒置、控制反转、依赖注入等原则就是人们在和依赖关系进行艰苦卓绝的斗争过程中不断产生和发展起来的

posted @ 2015-07-29 16:47  一天一夜  阅读(408)  评论(0)    收藏  举报