> to ajoo:
> 你的c.instance()本身是单态的方式,系统中就是由于过度的单态和工> 厂方式,使得测试等非常困难。有时业务的组合往往就是书写在这些工> 厂和单态类之后,难以扩展和灵活应用。
好象我的例子又造成误会了。
我的意思是,pico完全依赖共有构造函数来完成注射。这不够灵活。注射实现除了用setter, 用构造函数,也可以用工厂方法的。客户完全可能选择隐藏构造函数而使用工厂方法来注射。
这和用singleton, 工厂好不好是两码事。客户应该有设计的自由。pico作为一个号称很灵活的库,不应该对客户的设计提出太苛刻的需求。宣称“过度使用工厂不好”而不支持工厂和singleton怎么看都是巧言令色。实际上,工厂方法除了在reflection里面没有一个固定的命名标准,在传统的编程模型里,明显比构造函数有更好的灵活性。
另外,从c.instance()是看不出来是否单态的。实现者完全有自由让它是单态或者直接调用私有的构造函数。
>
> 另外,IOC已经被Martin大叔给命名为依赖注射,那么类A与类
> 有依赖关系的代码就是:
> class AImpl{ B b = new BImpl(); }
> 如果B实现换成BImpl1那么AImpl代码就要改动,复用性和扩展
> 远疾睢U馐欠浅<虻サ睦恿恕2还嗍讼衷谑樾吹拇胫
> 充斥着这样的代码。
>
没有人怀疑ioc的作用。我倒是有点奇怪这么个基本的面向接口的常见做法也需要这么长篇幅来解释。
这里讨论的是用pico方式实现ioc的作用。
> 我不熟悉PICO,但我在使用SPRING,它的bean and
> application
> context就象一个容器一样,不仅仅管理业务层对象之间那种?> 时的依赖关系,而且数据层等也一样容易被管理。方式就是加
> XML文件。如我上篇所提到的,这种依赖关系的代码一定要剔
> S行┕居檬菘饨ū淼姆绞焦芾恚SPRING给你一个这样?> 抽象类,使这一过程非常简单。
>
我不喜欢用setter来注射实现,这一方面有非法状态的问题(假如我忘了注射实现怎么办?),另一方面,它强迫我不能使用immutable的设计,这点很让人反感。
> 这样做的结果便是代码中只有接口在互相交互。具体的实现都在XML文件> 中指定。不仅仅如此,上下文和bean的加载就是一个组合的模式。这样> 是控制器和业务层,数据层的组合在更高一级组合。如果说原来写“管> 道”代码,现在就是在建楼房。楼房要一层一层建,建好后在去粉刷,> 装修,这些就会用AOP了。不仅仅日志管理,事务管理也是一个典型的应> 用。spring已经提供了和EJB一样的声明式事务管理。欠缺的可能就是象> JBUILDER的选取和自动生成吧。
接口互相交互是面向接口编程的理想状态。但是“具体的实现都在xml文件中”就不是面向接口的精神了。
其实,具体实现到底在哪里给出,完全是程序员自己灵活决定的,
从ptoprties,从gui,从xml文件,从jndi,从pico,从abstract factory,从rmi接口,所有的方式都有它们存在的合理性和必要性。
用xml配置这样一种方法来一统天下,思想显得太僵化了。面向接口的好处就是实现灵活,没有一定之规。
总而言之,一个好的库,或者框架,应该是尽量和客户代码orthogonal的,也就是说,它不对客户代码和设计方法做任何限制,任何强迫。
一个好的习惯是,用接口描述库和客户代码之间的协议。
反例如:
1。要求客户继承某一个鸡肋。这就剥夺了客户类继承其它鸡肋的权力。
2。要求客户类的构造函数共有。这就剥夺了客户用工厂方法的自由。
3。要求客户类提供setter,这就剥夺了客户类immutable的自由。而且强迫客户类增加可能本来不需要的状态(如uninitialized)
pico在我看来就有2这个毛病。当然,从pico的体系上来看,支持工厂方法也不是难事。只要pico的设计者认为值得为了这个灵活性在pico的接口里增加方法。(我认为是值得的)