锁定老帖子 主题:难以理解的工厂方法模式
精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-02-20
以前的项目很少考虑设计模式,也许不经意间已经使用了,但是自己并不知道。 但是为了更好的应用这些模式,所以想系统的学一下,没想到一开始就被最简单的工厂方法模式给吓倒了。 请参考:http://www.dofactory.com/Patterns/PatternFactory.aspx 我实在不知道这个东西到底有什么用,彻头彻尾的鸡肋一个。 因为工厂方法模式要求一个工厂类对应一个产品类,所以工厂类和产品类都是成对出现的。 于是从所有的例子中,我只看出了,使用了工厂方法模式后,仅仅多出了创建工厂类的代码,没有看出有任何的好处。 首先,它没有符合“开闭原则”,因为实例化的操作从产品类转移到工厂类。如果说把使用配置文件,动态load来实现“完全”的开闭原则的话,那么产品的抽象类或者借口也可以做到。 其次,他没有减少实例化的次数,因为工厂对应产品,产品添加了,工厂也势必添加,工厂类同样需要实例化。有人说,工厂类可以一次实例化,就可以多次使用实例化产品类,这样如果产品类增加了的话,只要更改一下工厂类就可以了,客户端的调用不变,我觉得很奇怪,如果产品类增加或者改变的话,工厂类岂不是也一样要增加或者改变才可以。 最后,他没有并不是隐藏创建细节的最好选择,在实例化产品类时,如果是类内部的数据,势必要在类内部创建,如果是类的开放数据,那么builder模式也就可以了。 我几乎看了网上所有的例子,没有一个阐明了为什么,什么时候使用工厂方法模式,也没有一个让我觉得应用它比不用它会在项目中需求的变化中带来好处。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-02-20
weiqingfei 写道 第一次在这儿发帖,以前都是在CSDN混得,我知道各位老大及其讨厌把这儿变成第二个CSDN,所以我力求把问题问的专业些,不过毕竟是第一次发帖,难免会带有一点儿CSDN的味道,还希望老大们海涵。
不是CSDN不好,只是不习惯CSDN的鱼龙混杂。 引用 以前的项目很少考虑设计模式,也许不经意间已经使用了,但是自己并不知道。
所为运用于心,以无招胜有招。 引用 但是为了更好的应用这些模式,所以想系统的学一下,没想到一开始就被最简单的工厂方法模式给吓倒了。 请参考:http://www.dofactory.com/Patterns/PatternFactory.aspx 我实在不知道这个东西到底有什么用,彻头彻尾的鸡肋一个。 读书而不信书,好样的 引用 因为工厂方法模式要求一个工厂类对应一个产品类,所以工厂类和产品类都是成对出现的。
此话差矣!工厂方法只是将实例化延迟到工厂子类,并没有说一个工厂类只能对应一个产品类 引用 于是从所有的例子中,我只看出了,使用了工厂方法模式后,仅仅多出了创建工厂类的代码,没有看出有任何的好处。
有以上误解,自然不识工厂方法之妙处了。 引用 首先,它没有符合“开闭原则”,因为实例化的操作从产品类转移到工厂类。如果说把使用配置文件,动态load来实现“完全”的开闭原则的话,那么产品的抽象类或者借口也可以做到。
工厂方法被归类到“创建模式”,重点不在于怎么创建产品,而是由谁来创建 引用 其次,他没有减少实例化的次数,因为工厂对应产品,产品添加了,工厂也势必添加,工厂类同样需要实例化。有人说,工厂类可以一次实例化,就可以多次使用实例化产品类,这样如果产品类增加了的话,只要更改一下工厂类就可以了,客户端的调用不变,我觉得很奇怪,如果产品类增加或者改变的话,工厂类岂不是也一样要增加或者改变才可以。
产品类的更改是否牵涉到接口的变更。如果接口变更了,修改量总是很大,所以我们不考虑会引起接口变更的改变了。 那么接口不变更的化情况如何? 我们将代码分成两部分,工厂生产部分的代码,和产品使用部分的代码。 如果接口不变,但是产品实现发生变化,只需要调整工厂类的代码,使用产品部分的代码至少不需要变化了。(虽然多数是理想情况) 引用 最后,他没有并不是隐藏创建细节的最好选择,在实例化产品类时,如果是类内部的数据,势必要在类内部创建,如果是类的开放数据,那么builder模式也就可以了。 这话正确,但是还是上面的我说了,工厂方法的目的是区分由谁来创建。有时候一个类既是builder,又是factroy也无不可。 引用 我几乎看了网上所有的例子,没有一个阐明了为什么,什么时候使用工厂方法模式,也没有一个让我觉得应用它比不用它会在项目中需求的变化中带来好处。 看整个项目的人员数量和分工情况。 如果只有按照业务功能划分,每个人从界面做到数据库,自然没觉得有好处,如果按照系统功能划分为界面,业务,数据库这种层次,那么界面开发人员调用业务功能可能就需要大家定义接口,创建工厂了。 比如, XXXService xxxService=XXXServeiceFactory.getXXXservice(); 毕竟让界面直接new 一个Service总是让人心里不太舒服。 |
|
返回顶楼 | |
发表时间:2007-02-20
你是指抽象工厂模式吧?子工厂对应不是一个对象,而是一系列对象。
|
|
返回顶楼 | |
发表时间:2007-02-20
dennis_zane 写道 你是指抽象工厂模式吧?子工厂对应不是一个对象,而是一系列对象。
不是,我说的是工厂方法模式。 |
|
返回顶楼 | |
发表时间:2007-02-20
工厂方法用处其实就是一个管理核心.里面可以管理全部类也可以只做一些分发请求的任务,给一个简单的例子:1个请求到工厂,工厂根据请求把产品做出来(或者有库存也可)交还给请求。这样的模式难道不是更好理解和更清晰吗,然后可以把一些其他东西也封装进工厂,比如所有的请求映射等.
|
|
返回顶楼 | |
发表时间:2007-02-20
pikachu 写道 引用 其次,他没有减少实例化的次数,因为工厂对应产品,产品添加了,工厂也势必添加,工厂类同样需要实例化。有人说,工厂类可以一次实例化,就可以多次使用实例化产品类,这样如果产品类增加了的话,只要更改一下工厂类就可以了,客户端的调用不变,我觉得很奇怪,如果产品类增加或者改变的话,工厂类岂不是也一样要增加或者改变才可以。 产品类的更改是否牵涉到接口的变更。如果接口变更了,修改量总是很大,所以我们不考虑会引起接口变更的改变了。 那么接口不变更的化情况如何? 我们将代码分成两部分,工厂生产部分的代码,和产品使用部分的代码。 如果接口不变,但是产品实现发生变化,只需要调整工厂类的代码,使用产品部分的代码至少不需要变化了。(虽然多数是理想情况) 如果是这样的话,那使用简单工厂模式就可以了呀。 我想工厂方法模式之所以把工厂抽象化,关键在于它想延迟产品的实现,但是同样又把工厂的实现提到前面了,使用者同样要知道哪个工厂才能生产自己所需要的产品。 |
|
返回顶楼 | |
发表时间:2007-02-25
我也 不好理解,为什么 不让 用 NEW ??工厂不也是NEW 了吗 ?
|
|
返回顶楼 | |
发表时间:2007-02-26
引用 工厂不也是NEW 了吗 ?
工厂似乎没有NEW 是用静态方法 也不是不让用NEW ,它只是统一管理你的产品 使你的产品可增可减 ,当然它不符合开闭原则 但是极端的设计也会带来弊端 |
|
返回顶楼 | |
发表时间:2007-02-26
工厂是对实列化做一个统一的管理,一般组合数量比较少的时候看不出它的好处,当组合多的时候就看出来了,特别你用抽象工厂的时候,把组合的选择交给了抽象类,对外是封装好的。
|
|
返回顶楼 | |
发表时间:2007-02-26
建议看看《effective java》,上面有说when and why使用工厂方法,以及其优点,缺点
|
|
返回顶楼 | |