论坛首页 Java企业应用论坛

关于Factory, Abstract Factory, Factory Method, 和Builder...

浏览 17179 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2005-12-06  
ajoo 写道
ioc容器的出现并不也从来不应该影响业务代码的设计。

如果你发现有些工厂因为有了ioc容器可以不用了,一般就是两个原因:
1。 这个工厂没有ioc容器的时候本来也不应该用,你只不过偷懒了,或者根本没有意识到这个错误。
2。根本就应该用工厂。你试图利用ioc容器来代替工厂的做法是错误的。


谢谢!


ajoo 写道

至于说用了ioc容器就和容器紧耦合了。也是两个原因:
1。这个容器产品不够好。侵入性太强。比如avalon,比如spring里面一些XXXAware的接口。

2。你用错了。依赖注入容器被你当作廉价的service locator了。拿菜刀去削铅笔你说是谁的错?


ajoo兄是指我说的“而且使用Ico和AOP后,我们就必须要和某些API建立了“紧耦合”么?

我的意思是,作为开发人员要学习使用某个container的API, 如果以后换container的话,还要学习新的API。而Dsign patterns和任何API和编程语言都是无关的。
0 请登录后投票
   发表时间:2005-12-07  
开发人员要学习容器的api做甚?容器的api是给你扩展容器用的(假设你用的是一个xml或者脚本外壳,而不是直接操作容器),大家平时没事都扩展容器来玩么?
0 请登录后投票
   发表时间:2005-12-07  
ajoo 写道
开发人员要学习容器的api做甚?容器的api是给你扩展容器用的(假设你用的是一个xml或者脚本外壳,而不是直接操作容器),大家平时没事都扩展容器来玩么?


第一次听到这种论调,请问你不用容器的API如何使用容器?

下面的例子我直接从martin fowler的Ioc文章里面copy过来的:

picoContainer:

private MutablePicoContainer configureContainer(); {
        MutablePicoContainer pico = new DefaultPicoContainer();;
        Parameter[] finderParams =  {new ConstantParameter("movies1.txt");};
        pico.registerComponentImplementation(MovieFinder.class, ColonMovieFinder.class, finderParams);;
        pico.registerComponentImplementation(MovieLister.class);;
        return pico;
    }


Spring:

public void testWithSpring(); throws Exception {
        ApplicationContext ctx = new FileSystemXmlApplicationContext("spring.xml");;
        MovieLister lister = (MovieLister); ctx.getBean("MovieLister");;
        Movie[] movies = lister.moviesDirectedBy("Sergio Leone");;
        assertEquals("Once Upon a Time in the West", movies[0].getTitle(););;
    }


有没有用到API, 不言而喻了吧!
0 请登录后投票
   发表时间:2005-12-07  
可能你没有理解ajoo的意思,他说容器的api应该是指关于容器内部infrastructure实现的,容器提供出的public api是可供客户端调用的,他所谓的扩展应该是指客户端通过继承或者使用包装,或者用兄弟你掌握的dp来纳入你的应用中,这称为客制化,但大多数时候,我相信spring的facade api已足够好,没有什么理由再去客制了
0 请登录后投票
   发表时间:2005-12-07  
ajoo 写道
ioc容器的出现并不也从来不应该影响业务代码的设计。

至于说用了ioc容器就和容器紧耦合了。也是两个原因:
1。这个容器产品不够好。侵入性太强。比如avalon,比如spring里面一些XXXAware的接口。

2。你用错了。依赖注入容器被你当作廉价的service locator了。拿菜刀去削铅笔你说是谁的错?


关于第一点,我有些补充,使用某一特定容器,必然会产生对该容器环境的一些依赖,好的容器实现应该是说能够体现出以最少的成本,来消除这种依赖的能力
,如果你真的需要完全脱离容器,可以用上发贴这位兄弟所倡导的dp之adapter来使用容器api,dp的adapter是个很有用的pattern,有时候可以用来处理许多杂碎的活儿

关于第二点,我有些疑问,ioc容器不能用作service locator吗,service locator引自j2ee core pattern,是在ejb身上被广泛采用的pattern,如果采用重量级容器,势必由service locator这个单访问点,籍由jndi创建或者cache出context来得到某个重量级对象的引用,而使用spring这样的轻量级容器,原则倡导without ejb,那么service locator应该也同样有理由可以lightweight吧,spring的appcontext应该可以看作是个廉价的service locator,我是说如果你需要把它看作是个locator的时候,也就是说把bean id看作是jndi,当然你也可以自己去实现一个singelton locator来使用spring的这个appcontext,你的意思是不是指不经加工,裸露使用这个context吗,是的,的确这样不好,还是有其他你认为不好的把ioc容器用作service locator的坏的例子吗
0 请登录后投票
   发表时间:2005-12-08  
polygoncell 写道
ajoo 写道
开发人员要学习容器的api做甚?容器的api是给你扩展容器用的(假设你用的是一个xml或者脚本外壳,而不是直接操作容器),大家平时没事都扩展容器来玩么?


第一次听到这种论调,请问你不用容器的API如何使用容器?

这种common sense不用我来说了吧。

当然在最顶层,bootstrap的时候,比如说那个main()函数里面,需要调用一下spring/pico/whatever的api来拿到你的那个或者那几个最顶层的对象。这还用说?

我是说除了bootstrap,任何其它的代码,比如业务代码里面就不要依赖容器。而bootstrap的代码就那么几行,集中在一个地方,耦合不耦合的有什么大不了的问题?

class Bootstrap{
  public void bootstrap();{
    Application app = (Application);container.getInstance("app");;
    app.start();;
  }
}
0 请登录后投票
   发表时间:2005-12-08  
引用
关于第二点,我有些疑问,ioc容器不能用作service locator吗,service locator引自j2ee core pattern,是在ejb身上被广泛采用的pattern,如果采用重量级容器,势必由service locator这个单访问点,籍由jndi创建或者cache出context来得到某个重量级对象的引用,而使用spring这样的轻量级容器,原则倡导without ejb,那么service locator应该也同样有理由可以lightweight吧,spring的appcontext应该可以看作是个廉价的service locator,我是说如果你需要把它看作是个locator的时候,也就是说把bean id看作是jndi,当然你也可以自己去实现一个singelton locator来使用spring的这个appcontext,你的意思是不是指不经加工,裸露使用这个context吗,是的,的确这样不好,还是有其他你认为不好的把ioc容器用作service locator的坏的例子吗


ioc容器当然可以拿来当作service locator。只不过买椟还珠罢了。理想的情况就是用容器组装对象。从容器中把对象拿出来后(拿的时候当然还是service locator,就象你不管怎么抽象,怎么工厂,怎么ioc,最终总要有个地方具体地new一样),就跟容器说byebye了。所有的依赖关系都已经处理干净了,所有你需要的service都已经注射给你了,你还locate个啥呀?
0 请登录后投票
   发表时间:2005-12-08  
ajoo 写道
这种common sense不用我来说了吧。

当然在最顶层,bootstrap的时候,比如说那个main()函数里面,需要调用一下spring/pico/whatever的api来拿到你的那个或者那几个最顶层的对象。这还用说?

我是说除了bootstrap,任何其它的代码,比如业务代码里面就不要依赖容器。而bootstrap的代码就那么几行,集中在一个地方,耦合不耦合的有什么大不了的问题?

class Bootstrap{
  public void bootstrap();{
    Application app = (Application);container.getInstance("app");;
    app.start();;
  }
}


1。 老兄在整个系统中integrated某个Ioc container,却只用来获得几个最顶层的对象,是不是有点舍近求远了,为了用Ioc container而用Ico container? 如果只是为了获得区区几个对象, 直接生成不就行了,何必绕这么大一个圈?

2。假设我们获得了最顶端的几个对象,那么请问你如何获得其他对象?全部通过这几个最顶端的对象来获得?不太现实了吧!通过容器而又不是用容器的API来获得对象?可能实现么?

3。Ioc的最大好处是使得POJO们之间解耦合, 如果POJOs和容器产生了耦合,那绝对是用错了。 我说的耦合是系统和某个Ico container产生耦合(通过API)。 从你的例子来看,对象应该通过xml配置文件来实现,而系统是通过某个container的API来解读xml进而生成相应的对象的,即使开发人员没有在编码中呼叫这些API(这个是不可能避免的),我们也不能说系统和这个container是解耦合的,因为系统用到了这些API。如果不用xml,  那就得用代码呼叫API注入对象,更是耦合。

p.s. 本来我是不想谈Ioc的,可是没有办法,大家眼里只有Ioc。大家真的没有必要把Ioc抬得这么高,她也不过就是个pattern, 不比其他pattern高多少。眼光放的开阔些。
0 请登录后投票
   发表时间:2005-12-08  
spiritj 写道
可能你没有理解ajoo的意思,他说容器的api应该是指关于容器内部infrastructure实现的,容器提供出的public api是可供客户端调用的,他所谓的扩展应该是指客户端通过继承或者使用包装,或者用兄弟你掌握的dp来纳入你的应用中,这称为客制化,但大多数时候,我相信spring的facade api已足够好,没有什么理由再去客制了


准确些,应该是ajoo没有理解我的意思,我说的是"某些API",  facade API难道不是容器的某些API么?在朝这个方向讨论下去可就成了讨论汉语语义了
0 请登录后投票
   发表时间:2005-12-08  
引用
2。假设我们获得了最顶端的几个对象,那么请问你如何获得其他对象?全部通过这几个最顶端的对象来获得?不太现实了吧!通过容器而又不是用容器的API来获得对象?可能实现么?

现实,太现实了。ioc容器就是这么用的。

“获得其它的对象”?你还不懂什么叫ioc(更精确地说:dependency injection)吧?这外行话也说得出来?

所谓依赖注入就是根本不主动获得其它对象。你需要什么都已经注射给你了,还苦哈哈地“获得”个什么劲?


“直接new”?说的轻巧。还是不懂ioc的问题。你当就"new App()"这么简单?App的dependency你要注入吧?它的dependency的dependency要注射吧?这些从属对象的生命期要管理吧?这么一整张复杂的对象网络你就new一下就都出来了?知道什么叫"wiring"么?容器不过就是负责管理对象的依赖并把整个对象网络构造起来而已。说难不难,但是也不象你想的那么简单。



不懂就谦虚点吧,同学。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics