关于工厂模式的问题
问?:
首先定义一个概念:什么是代码不影响--1.只加入一个类,其他包括client和server都不用修改代码,而程序运行的结果就会产生相应于那个加入的类的期望输出.
那么工厂模式是否达到了这个目标呢?就以简单工厂模式来说
加入了新类之后:
1.server端从接口或抽象类继承产生一个新的product类,不影响server的其他代码,是可插入性的.
2.如果不使用工厂方法,client端使用新产品的时候必须构造这个新产品类,起码的,必须使用
abstractproduct p1=new newproduct(); 其他的可以保持不变.
3.如果采用工厂方法,代码为,abstractproduct p1=creatot.factory("newproduct");这里的代码不是也要改变吗???????????????
4.两者的区别仅仅是后者用一个统一的界面封装了new操作.
我的问题是:
这两者的区别到底有多大,使用了工厂方法之后到底有什么好处呢?
个人想法:
1.这里的好处首先如上所说是用一个统一的界面封装了new操作,这个界面更好.
2.其次是整个系统的代码可以分离开发,只要遵守一定的接口规范.
3.是否真的不需要修改client的代码了呢?这是个问题.
4.难道仅仅是这么些好处吗?
那么工厂模式是否达到了这个目标呢?就以简单工厂模式来说
加入了新类之后:
1.server端从接口或抽象类继承产生一个新的product类,不影响server的其他代码,是可插入性的.
2.如果不使用工厂方法,client端使用新产品的时候必须构造这个新产品类,起码的,必须使用
abstractproduct p1=new newproduct(); 其他的可以保持不变.
3.如果采用工厂方法,代码为,abstractproduct p1=creatot.factory("newproduct");这里的代码不是也要改变吗???????????????
4.两者的区别仅仅是后者用一个统一的界面封装了new操作.
我的问题是:
这两者的区别到底有多大,使用了工厂方法之后到底有什么好处呢?
个人想法:
1.这里的好处首先如上所说是用一个统一的界面封装了new操作,这个界面更好.
2.其次是整个系统的代码可以分离开发,只要遵守一定的接口规范.
3.是否真的不需要修改client的代码了呢?这是个问题.
4.难道仅仅是这么些好处吗?
答!: 1:
工厂可以控制类实例的数量
答!: 2:
http://community.csdn.net/Expert/topic/4928/4928140.xml?temp=.7220575
答!: 3:
schumiXsuse() 的有点道理.
不过那基本上变成了单例模式或是多例模式了.
不过那基本上变成了单例模式或是多例模式了.
答!: 4:
2.如果不使用工厂方法,client端使用新产品的时候必须构造这个新产品类,起码的,必须使用
abstractproduct p1=new newproduct(); 其他的可以保持不变.
3.如果采用工厂方法,代码为,abstractproduct p1=creatot.factory("newproduct");这里的代码不是也要改变吗???????????????
========================================================
你的思路不太对……
首先,其实工厂模式也不是完全吻合开闭原则的,没有某一个设计模式是完美的。
再说说你的问题,你说
只加入一个类,其他包括client和server都不用修改代码,而程序运行的结果就会产生相应于那个加入的类的期望输出.
这个…… 不知道怎么想的。 对这个问题最狭隘的理解至少也应该是加入新的Production的时候不需要对原有的代码进行修改,具体client端使用某个产品是由client端选择的,它既然已经选择创建某个production,那么肯定就会创建相应的产品,输出结果怎么会变?
既然说到了SimpleFactory ,他只是告诉你一种形式和思想,具体能灵活到什么程度就看你了,比如你可以将这个工厂与一个XML文件相对应,这样加入新产品的时候你只需要培植相应的xml文件就可以了
答!: 5:
我说的是我理想中的定义:
发生的情况是有的,不过是相对某一块代码而言,比如一段用抽象类或接口实现的函数代码,这里你只要改变输入的参数,就能得到期望的输出(具体输出由具体类实现的函数决定).
但是这并不意味着就不需要修改代码了,起码的你在参数调用的时候是需要的,于是问题归结为在哪里修改代码.
我对模式的思考是基于如何适应变化的,因为变化必然得是需要修改代码的,只是程度问题,我上面的提问是想说使用了简单工厂模式和仅仅是利用类的多态,两者要改变代码的多少其实是没多大区别的,那这样的好处似乎也就并不是很多了.于是我疑惑于使用简单工厂模式带来的好处到底有多少.
当然仅仅从修改代码的角度并不是周详的,于是我问有没有其他更明显的好处.
发生的情况是有的,不过是相对某一块代码而言,比如一段用抽象类或接口实现的函数代码,这里你只要改变输入的参数,就能得到期望的输出(具体输出由具体类实现的函数决定).
但是这并不意味着就不需要修改代码了,起码的你在参数调用的时候是需要的,于是问题归结为在哪里修改代码.
我对模式的思考是基于如何适应变化的,因为变化必然得是需要修改代码的,只是程度问题,我上面的提问是想说使用了简单工厂模式和仅仅是利用类的多态,两者要改变代码的多少其实是没多大区别的,那这样的好处似乎也就并不是很多了.于是我疑惑于使用简单工厂模式带来的好处到底有多少.
当然仅仅从修改代码的角度并不是周详的,于是我问有没有其他更明显的好处.
答!: 6:
我在前面留的那个贴子里说了,工厂模式相比一般的构造函数,最大的好处在于,它能产生出其所属的类的任何之类的实例,而构造函数只能产生其所属的类的实例,这样更灵活
还有一点就是工厂模式不必每次都产生一个新的对象,它可以返回一个被缓存的对象,而构造函数每次都要产生一个新的对象
还有一点就是工厂模式不必每次都产生一个新的对象,它可以返回一个被缓存的对象,而构造函数每次都要产生一个新的对象
答!: 7:
同意sonyejin(这年头和尚都会.NET!),原谅我没仔细看你给的帖子.
"我在前面留的那个贴子里说了,工厂模式相比一般的构造函数,最大的好处在于,它能产生出其所属的类的任何之类的实例,而构造函数只能产生其所属的类的实例,这样更灵活"——这段话我想做这样的理解——其实和我前面说的只是提供了一个更清楚的接口而已。因为在声明一个实例的时候,工厂的界面确实如你所说可以提供“所属的类的任何子类的实例”,只用一个factory(“asdj”)方法,而构造函数只能是一个“所属的类的实例”。这其实就是封装了new方法,因为new是违反依赖倒转的。
很多模式都是为了提供一个更好的界面而已,这个界面使你能依赖更高的抽象。
另“还有一点就是工厂模式不必每次都产生一个新的对象,它可以返回一个被缓存的对象,而构造函数每次都要产生一个新的对象”-----这个应该是单例模式的内容吧,虽然工厂模式和单例模式是可以很容易发生关系的。
"我在前面留的那个贴子里说了,工厂模式相比一般的构造函数,最大的好处在于,它能产生出其所属的类的任何之类的实例,而构造函数只能产生其所属的类的实例,这样更灵活"——这段话我想做这样的理解——其实和我前面说的只是提供了一个更清楚的接口而已。因为在声明一个实例的时候,工厂的界面确实如你所说可以提供“所属的类的任何子类的实例”,只用一个factory(“asdj”)方法,而构造函数只能是一个“所属的类的实例”。这其实就是封装了new方法,因为new是违反依赖倒转的。
很多模式都是为了提供一个更好的界面而已,这个界面使你能依赖更高的抽象。
另“还有一点就是工厂模式不必每次都产生一个新的对象,它可以返回一个被缓存的对象,而构造函数每次都要产生一个新的对象”-----这个应该是单例模式的内容吧,虽然工厂模式和单例模式是可以很容易发生关系的。
答!: 8:
我其实想比较的是两者代码的修改程度问题,但我明白了,其实要考虑更多的是一个界面。而不仅仅是适应变化的代码修改。
答!: 9:
可以完全不用修改原来代码,方法很简单,你把各个“产品”的class名放到资源文件中既可。
新“发布”一个产品的时候,只要写新的产品类,然后修改下资源文件,就可以了。
新“发布”一个产品的时候,只要写新的产品类,然后修改下资源文件,就可以了。
答!: 10:
工厂方法实际是对 "使用new创建对象" 的封装. new 本身并没有什么不可以,只要没有变化完全可以直接使用new来创建对象, 而工厂模式将 "使用new创建对象" 封装到一个方法中,这样的目的是应对的是当 "使用new创建对象" 不能满足的情况.
楼主的"只加入一个类,其他包括client和server都不用修改代码,而程序运行的结果就会产生相应于那个加入的类的期望输出." 观点有误. 世界上根本就没有100%的"开闭原则",设计模式并不是完美无暇的,每一种设计模式都是针对解决某种特定的问题的.这里说的"问题"实际就是"变化".显然工厂模式(或者简单工厂模式)解决的问题就是直接使用new创建对象在某种特定情况下无法灵活改变的问题.
实际上"使用new创建对象" 就是 "对实现进行编程"
而使用工厂方法则是:"对接口进行编程"
这是设计模式的一个原则.
楼主的"只加入一个类,其他包括client和server都不用修改代码,而程序运行的结果就会产生相应于那个加入的类的期望输出." 观点有误. 世界上根本就没有100%的"开闭原则",设计模式并不是完美无暇的,每一种设计模式都是针对解决某种特定的问题的.这里说的"问题"实际就是"变化".显然工厂模式(或者简单工厂模式)解决的问题就是直接使用new创建对象在某种特定情况下无法灵活改变的问题.
实际上"使用new创建对象" 就是 "对实现进行编程"
而使用工厂方法则是:"对接口进行编程"
这是设计模式的一个原则.
答!: 11:
"当 "使用new创建对象" 不能满足的情况."_______不懂这句话的意思.
我的定义是理想的,只在某段代码块是可行的.有说明的 :)
显然工厂模式(或者简单工厂模式)解决的问题就是直接使用new创建对象在某种特定情况下无法灵活改变的问题.___________这种情况不是很了解.能简单指点一下吗.
如果只是用一个函数.factory()封装了new,那与直接使用new,好象没什么是不可替代的.
最后的一段同意.
我的定义是理想的,只在某段代码块是可行的.有说明的 :)
显然工厂模式(或者简单工厂模式)解决的问题就是直接使用new创建对象在某种特定情况下无法灵活改变的问题.___________这种情况不是很了解.能简单指点一下吗.
如果只是用一个函数.factory()封装了new,那与直接使用new,好象没什么是不可替代的.
最后的一段同意.
答!: 12:
不能满足的情况和无法灵活改变的问题:
一是,与构造函数不同,静态工厂方法具有名字。静态工厂方法能够清晰的表示出意图,看看JAVA2中的为数众多的valueOf()和getInstance()方法就明白了.
二是,与构造函数不同,它们每次被调用的时候,不要求非得创建一个新的对象。静态使然.
三是,与构造函数不同,它们可以返回一个原返回类型的子类型的对象。针对接口编程.
一是,与构造函数不同,静态工厂方法具有名字。静态工厂方法能够清晰的表示出意图,看看JAVA2中的为数众多的valueOf()和getInstance()方法就明白了.
二是,与构造函数不同,它们每次被调用的时候,不要求非得创建一个新的对象。静态使然.
三是,与构造函数不同,它们可以返回一个原返回类型的子类型的对象。针对接口编程.
答!: 13:
1.更好的界面
2.factory本身是静态的,或构造的对象类型不存在(factory("NotHaveIt"),或单例返回上次创建的对象----不知道你指的是哪种情况.
3.应该就是指定义factory()的返回类型是接口或抽象类吧.
向你的回复敬礼!
2.factory本身是静态的,或构造的对象类型不存在(factory("NotHaveIt"),或单例返回上次创建的对象----不知道你指的是哪种情况.
3.应该就是指定义factory()的返回类型是接口或抽象类吧.
向你的回复敬礼!
答!: 14:
2. JAVA5.0中的Boolean类实现.
public final class Boolean implements java.io.Serializable,
Comparable<Boolean>
{
//...略
public static Boolean valueOf(boolean b){
return ( b ? Boolean.TRUE : Boolean.FALSE);
}
它就不创建新的对象.
3.返回一个原返回类型的子类型的对象,这样就能在选择被返回对象类型的时候有更大灵活性.比如可以返回一个对象,而同时将此对象的类声明为非公有的.这在框架设计的时候非常有用.客户代码了解的只是接口,而不是具体的实现类.
public final class Boolean implements java.io.Serializable,
Comparable<Boolean>
{
//...略
public static Boolean valueOf(boolean b){
return ( b ? Boolean.TRUE : Boolean.FALSE);
}
它就不创建新的对象.
3.返回一个原返回类型的子类型的对象,这样就能在选择被返回对象类型的时候有更大灵活性.比如可以返回一个对象,而同时将此对象的类声明为非公有的.这在框架设计的时候非常有用.客户代码了解的只是接口,而不是具体的实现类.
答!: 15:
谢谢nirvana_li兄.
相关JAVA教程:
请问怎样用jsp调用华为3com的NBXOCX.OCX控件,越详细越好最好贴上代码。在线等
做个高人气网站 帮忙选个域名
求助:用reflect实现远程调用的例子
applicationContext.xml文件出错
请问如何在border上加一组button?
我该怎么办,请问?
求助,在java中,如何生成静态的html文件
高手赐教web service简单问题.
ejb的发布
JBoss web service REPLACE_WITH_ACTUAL_URL
在IBMwebsphere Application Server5中如果部署NetBeansIDE5开发的项目?
写了一篇OpenCms 使用初步印象