IoC & Extension Point

IoC & Extension Point

昨天在fog讨论到这个问题,fog认为Extension Point是按照IoC的思路实现出来的,我来谈谈我的观点,我却认为Extension Point并不是按照IoC思路来实现的,甚至可以说两者没有关系。
首先来说说IoC,IoC,全称Inversion of Control,Martin Fowler认为这个词有些不恰当,建议改为DI,为什么呢?其实这是因为IoC的本质决定的,IoC是什么,其主要作用是解耦,分离关注点,通俗点说就是使得调用者和被调用者之间没有直接的耦合,而只是接口的耦合,举例来说:

在没用IoC实现的时候是这样的:

public   class  A {
 
 
public void execute(){
  B b
=new BImpl();
  b.execute();
 }


}


可见在这里造成的一个问题就是调用者A和被调用者B的实现构成了一个直接的依赖,为什么Martin Fowler要建议改名成DI呢,原因就在这了,这里造成的是抽象对实现的依赖,这不用说,是严重违反OO中依赖抽象而不依赖实现这一原则的,所以称为DI确实更符合一些。

再来看一下使用了IoC后是这样的:

public   class  A {
 
 
private B b;

 
public void setB(B b){
  
this.b=b;  
 }


 
public void execute(){
  b.execute();
 }
 

}


可见在这里调用者A和被调用者B是接口的依赖,而不是实现的依赖,这就实现了调用者对于被调用者具体实现依赖的解耦。
当然,也许诸位看官会说可以用Factory之类的模式来实现对具体依赖的解耦,但那样同样造成一个问题就是调用者和被调用者的Factory耦合,而在IoC中是不会有这个问题的,调用者和被调用者之间只有清晰的接口依赖。
根据上面这些解释,我们可以看出IoC最大的好处在于解耦调用者对于被调用者具体实现的依赖。

现在来说说Extension Point,Extension Point是Eclipse为支持Plugin扩展而做的一种设计,举例来说吧,在工具栏这个Plugin中,必然需要提供某种方法能使得其他Plugin可加入按钮至工具栏中,那么该怎么去做呢,在Extension Point中是这么实现的,工具栏Plugin提供了一个这样的Extension Point,其他的Plugin只需要实现这个Extension Point即可加入按钮至工具栏中,工具栏的Plugin在可扩展的地方通过对于容器中Extension Point注册信息的获取来取得所有实现了当前Extension Point的类,并相应的进行调用。
这里还是得罗嗦一下Extension Point的实现思路,在Eclipse中是这么做的,首先它会根据各Plugin提供的Extension Point构成一个Extension Point的信息集合,之后根据各Plugin提供的Extension Point的实现构成Extension Point Registry,而各提供了Extension Point的Plugin必然会在可扩展的地方调用这个Registry获取相应实现了此Extension Point的集合,通过所提供的Extension Point Interface做相应的callback来实现扩展。
首先我们来看,如果Extension Point是采用IoC思想来实现的,那么我们可以按照IoC思想来进行分析,那么提供Extension Point的Plugin就是调用者,提供Extension Point实现的Plugin就是被调用者,按照IoC思想是为了解耦调用者对于被调用者实现的依赖,那么我们可以看出这个命题是不成立的,这里的关键在于提供Extension Point的Plugin并不依赖于实现Extension Point的Plugin,它才不关心哪些Plugin实现了它的Extension Point,没有直接的依赖关系又何来IoC一说。
其次我们来看Extension Point的设计目的是为了什么?它设计的目的是为了Plugin可被扩展,而不是说用于解除Plugin之间依赖的问题。
其实Extension Point的设计思路很简单,是类似Template的模式,只是它把所有实现了此Template的信息都集中存储了,并且由提供了Template的类去获取了所有的这些信息,鉴于此我还是坚持自己的观点Extension Point并不是按照IoC的思想来设计的,两者并没什么关系。

你可能感兴趣的:(IoC & Extension Point)