对依赖注入的一点想法

对于spring中的IOC,大家都知道这个仅仅是对属性的依赖注入,也就是这种方式解决了类与类之间的依赖问题。现在大家的讨论好像都集中在域模型的是否充血的问题上,就是说是否给模型加上行为(业务方法)。这样我就想有没有一种方式可以实现方法的依赖注入的问题,这样是否就可以更大的解耦了呢?
初步想法是这样的:
public class A{
String name;
IBehavior behavior;
public doA(){
behavior.doA(this.name);//委托给行为类
}
public doB(){
behavior.doB(this.name);
}

}

public interface IBehavior{
public doA(String aparam);
public doB(String aparam);
}

public abstract class AbstractBehavior implements IBehavior{
// 默认实现
}

自己通过extends AbstractBehavior 类或者implements IBehavior 也可以实现自己特定的要求再通过spring的IOC把依赖关系注入,通过改变这个注入的类可以改变类A的行为

调用就需要:context.getBean("a").doA();

不过现在觉得现在这样的实现有种画蛇添足的感觉!

不知道大家对方法的注入有什么想法?不知道能否直接实现方法的注入而不是通过这这样的间接的方式!


PS:我看Jdonframework对于struts 中的几个saveAction,updateAction等的处理好像就是通过配置来实现方法的委托的,好像这个也可以说是方法的注入吧。


[该贴被pliaozrlp于2009-06-18 16:39修改过]

很好的想法。

>通过改变这个注入的类可以改变类A的行为

其实行为如果需要变化拓展,那么可以将行为抽象为单独的行为类,然后使用属性依赖注射。

行为和属性都可以动态转为另外一个对象,这就是对象设计的魅力和灵活性。

谢谢banq的回复!
这个只是个最初的想法。其实我心中最完美的解决方案是(以spring为例):
<bean id="a" class="A">
<property name="name"><value>XXX<value></property>
<method name="doA"><value>行为类的全限定名</value></method>//通过这样的声明就完成了方法的注入
</bean>
这样的话就把行为类的同名方法所完成的行为注入到类A中的,而在类A中我要做就是就是一个方法的声明

这样做的话就可以说实现了方法像属性一样的注入了

好像通过spring的look-up和replaced-method可以实现这样的功能!


[该贴被pliaozrlp于2009-06-19 11:13修改过]

》》behavior.doB(this.name);

这样不可取 我觉得应该是 behavior.doB(this.classname);不同的class决定不同的行为。不过觉得可以使用继承的方式来实现。

>behavior.doB(this.classname);不同的class决定不同的行为
这样的话怎么把类A的属性作为参数传递给行为方法呢?

很有创意,有意思

实际你可能完成的是一个接口和实现的重要对象关系。不过,也可能会延伸出一个新设计概念,对象之间关系以往我们主要重视属性关系,也就是关联,关联分紧耦合和松关联,对于松关联的依赖我们使用注射。

但是,对象之间关系也可以有行为上,如合约Contract关系等,按照上面属性的思路,那么也可以对松依赖进行注射,理论上逻辑是有道理的哦

behavior.doB(this);那就这样就可以了。不够这样不是一个好的办法,无法访问private的,定义接口然后实现就好了,为什么要弄得那么复杂??

>behavior.doB(this);那就这样就可以了
这样不是造成A依赖behavior,behavior又依赖A

我不是想弄的这样复杂,我是想找到一种方法,像注入属性一样把方法也注入进去

通过spring的replace-method已经可以实现动态的替换一个类的方法,但是这样的话跟spring的API是造成了一定的耦合,而且对于一个方法要实现你个替换类进行替换。有点麻烦,还是没达到我的理想中的那种注入
[该贴被pliaozrlp于2009-06-19 12:55修改过]

我也曾经尝试过这样的路子,结果不太理想,但我不怀疑大体方向。楼主不妨继续尝试。
behavior和a双向关联没什么问题,关键要保证a的具体行为是不是都被behavior涵盖。而且这个行为是针对具体对象的,如果碰上对一批对象的作业,让某个对象拥有这个行为就显得很不协调。

>关键要保证a的具体行为是不是都被behavior涵盖。而且这个行为是针对具体对象的,如果碰上对一批对象的作业,让某个对象拥有这个行为就显得很不协调

这个不是很明白,能否详细说下,谢谢!

>如果碰上对一批对象的作业
对于这个我认为这就可以抽象为DDD中的服务了,而不应该把这样的行为单独的给一个对象

比方说a.optByOther(B b),有一个针对b的操作,那么behavior和a是否要包含这个操作。
如果不包涵,behavior就没什么太大意义了,如果包涵,那么会发现系统中很多这样的操作,而且经常会有新的操作需要加入,a将变得很不稳定。我实施的时候就是在这里碰到麻烦。

>比方说a.optByOther(B b),有一个针对b的操作,那么behavior和a是否要包含这个操作。
如果不包涵,behavior就没什么太大意义了,如果包涵,那么会发现系统中很多这样的操作,而且经常会有新的操作需要加入,a将变得很不稳定。我实施的时候就是在这里碰到麻烦。

这个问题我觉得是个为对象增加责任的问题了,在UML与设计模式中有讲到一种方法:最大信息的法(不记得是否是这个名字)
我个人觉得如果对象b是在以a为聚合根的聚合之中,就是说a本身在领域模型中已经依赖了b的话,那么这个操作就应该放在a中,如果不在的话就把它放到服务之中去,不然的话如果加进来的话就是增加依赖的复杂程度