简单工厂模式到底违反开闭原则吗?

踏雁寻花 2013-08-25 11:40:00
很多人都说简单工厂模式违反开闭原则,因为,如果新添加一个产品类,就需要修改工厂类中的代码。

我觉得如果简单工厂模式违反开闭原则,那么工厂方法模式也违反了开闭原则。

我的分析是这样的:

(这是我的一个分析的文章,http://blog.csdn.net/tayanxunhua/article/details/10297013,大家如果觉得我是打广告的,那么可以不看,我在这里再解释一下)

一个TV产品类,HaierTV和HisenseTV实现了这个类;
一个工厂类,还有一个测试类。

工厂类的实现:
public static TV getTV(String name) {
if (name.equals("Haier")) {
return new HaierTV();
} else if (name.equals("Hisense")) {
return new HisenseTV();
} else {
return null;
}
}
这样肯定是违反开闭原则的,原因就不说了。
但是如果我这样修改呢?
public static TV getTV(String name) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
TV tv = (TV) Class.forName("com.tyxh.pattern.sample." + name).newInstance();
return tv;
}

修改了之后,是否还违反开闭原则呢?

当然了,可能会有这种情况,现在有一个TV的产品类,如果我想再添加一个Fruit产品类,那么就需要修改工厂类的代码了吧。

我觉得简单工厂模式确实违反了开闭原则,但是工厂方法模式是否又违反了开闭原则呢?

我添加一个新的产品类的时候,不是也需要修改测试类的代码么?
...全文
1832 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
大智诺俞 2013-08-26
  • 打赏
  • 举报
回复
要想做好一个软件,不能单单一个设计模式就行的,就开闭原则来说,工厂方法加spring.net框架还是比较好的能实现开闭原则的,把要加载的内容放入xml或者app.config,这样在不用重新编译的情况下也可以修改加载项
aqbeyond 2013-08-26
  • 打赏
  • 举报
回复
开闭原则是一个理想化的东西,作为一个码农不遗余力的去坚持这样的原则是没有意义的。 想想如果开闭原则真的存在,那还需要那么多码农吗?
冰思雨 2013-08-26
  • 打赏
  • 举报
回复
修改代码无非就是添加映射关系。 楼主要是不想通过修改源码来添加映射关系,大可将映射关系写成配置文件,程序启动时加载配置文件即可。 程序是死的,设计模式也是死的,我觉得,设计程序,不应该死板硬套,非要纠结什么什么原则, 关键应该是以实际应用场景为依据,来设计程序。当然了,这可能会有部分源代码脱离了设计模式, 或者说,不完全是具体某个设计模式。 以前有个数据采集的小项目,我严格按照程序的设计模式去编写程序,虽然都能完成相应的功能, 程序的扩展性也非常的好,但是,执行效率比人家慢了八倍,并且, 我写的这个程序,后期基本没有什么扩展功能的可能性了。 于是,我从那以后,就不再纠结什么什么原则之类的了,关键看应用场景。
踏雁寻花 2013-08-25
  • 打赏
  • 举报
回复
是不是修改客户端测试类中的代码就不影响开闭原则呢?
踏雁寻花 2013-08-25
  • 打赏
  • 举报
回复
是不是修改客户端测试类中的代码就不算是对代码的更改了呢?
踏雁寻花 2013-08-25
  • 打赏
  • 举报
回复
好吧
  • 打赏
  • 举报
回复
引用 5 楼 tayanxunhua 的回复:
[quote=引用 3 楼 yang_lover 的回复:] 工厂方法模式并未能完全避免违反开闭原则啊~ 难道谁跟你说它没有违反开闭原则么? - - 工厂方法只是实现了对产品角色创建的封装,避免了工厂角色内部违反开闭原则~(简单工厂模式并未做到这一点~) 引用一句话来说明这个问题:“在工厂方法模式中,要么将判断逻辑留在抽 象工厂角色中,要么在客户程序中将具体工厂角色写死。而且产品 对象创建条件的改变必然会引起工厂角色的修改。”
这么说工厂的那三个兄弟都违反了开闭原则?[/quote] 楼上又人说的很好,只能尽量避免违反开闭原则~ 用反射机制也可以很好的解决这个问题~ 但是用了反射机制,就不是简单的工厂模式了,而是几种技术规范的结合使用~ PS:你纠结这个干嘛
踏雁寻花 2013-08-25
  • 打赏
  • 举报
回复
引用 12 楼 chengxu2011 的回复:
不能和反射比。。。你如果用了反射 那么还用什么简单工厂。。。
我觉得不影响啊,简单工厂用到了反射效果不是更好么?
valenon 2013-08-25
  • 打赏
  • 举报
回复
其实想问一下楼主的例子中为什么新增Fruit产品,还要把它挤到TV工厂里面去,Fruit定义一个自己的工厂不是很好吗?既然TV下面有子类,Fruit加到这个结构中,不是不伦不类吗?对Fruit没法和TV的子类们同等对待。应该是另外新增一个TV的子类差不多吧
chengxu2011 2013-08-25
  • 打赏
  • 举报
回复
不能和反射比。。。你如果用了反射 那么还用什么简单工厂。。。
valenon 2013-08-25
  • 打赏
  • 举报
回复
引用 7 楼 tayanxunhua 的回复:
[quote=引用 6 楼 valenon 的回复:] 设计模式并没有完美的,能看到它的闪亮点就行。 工厂方法本身是符合开闭原则的,但要说到客户端,客户总得自己决定创建什么样的对象吧,这个在服务端没法帮客户确定,所以客户端代码需要改是不可避免的。客户端要么自己创建具体的工厂类,要么通过类型参数,让服务端返回合适的对象。
那请问,简单工厂模式是否符合开闭原则呢?[/quote] 简单工厂在工厂类中进行判断,如果新增了类型,需要修改工厂类(不是客户端),当然是符合开闭原则的。暂不说使用反射。
踏雁寻花 2013-08-25
  • 打赏
  • 举报
回复
引用 8 楼 chengxu2011 的回复:
只能说在某种程度上实现了开闭原则,在某种程度上没有实现,比较简单工厂,对于调用工厂的客户端来说实现了开闭原则而工厂本身没有实现开闭原则。抽象工厂在横向上实现了开闭原则在纵向上没有实现。。。。。。没有十全十美的东西,只能尽力去符合开闭原则。。。。
您好,简单工厂模式中,如果在静态工厂方法里面不采用if..else逻辑,而是采用反射机制创建对象,那么对于工厂类来说还违反开闭原则了么?
踏雁寻花 2013-08-25
  • 打赏
  • 举报
回复
可以看一下我这个分析对不对么? http://blog.csdn.net/tayanxunhua/article/details/10297013
chengxu2011 2013-08-25
  • 打赏
  • 举报
回复
只能说在某种程度上实现了开闭原则,在某种程度上没有实现,比较简单工厂,对于调用工厂的客户端来说实现了开闭原则而工厂本身没有实现开闭原则。抽象工厂在横向上实现了开闭原则在纵向上没有实现。。。。。。没有十全十美的东西,只能尽力去符合开闭原则。。。。
踏雁寻花 2013-08-25
  • 打赏
  • 举报
回复
引用 6 楼 valenon 的回复:
设计模式并没有完美的,能看到它的闪亮点就行。 工厂方法本身是符合开闭原则的,但要说到客户端,客户总得自己决定创建什么样的对象吧,这个在服务端没法帮客户确定,所以客户端代码需要改是不可避免的。客户端要么自己创建具体的工厂类,要么通过类型参数,让服务端返回合适的对象。
那请问,简单工厂模式是否符合开闭原则呢?
valenon 2013-08-25
  • 打赏
  • 举报
回复
设计模式并没有完美的,能看到它的闪亮点就行。 工厂方法本身是符合开闭原则的,但要说到客户端,客户总得自己决定创建什么样的对象吧,这个在服务端没法帮客户确定,所以客户端代码需要改是不可避免的。客户端要么自己创建具体的工厂类,要么通过类型参数,让服务端返回合适的对象。
踏雁寻花 2013-08-25
  • 打赏
  • 举报
回复
引用 3 楼 yang_lover 的回复:
工厂方法模式并未能完全避免违反开闭原则啊~ 难道谁跟你说它没有违反开闭原则么? - - 工厂方法只是实现了对产品角色创建的封装,避免了工厂角色内部违反开闭原则~(简单工厂模式并未做到这一点~) 引用一句话来说明这个问题:“在工厂方法模式中,要么将判断逻辑留在抽 象工厂角色中,要么在客户程序中将具体工厂角色写死。而且产品 对象创建条件的改变必然会引起工厂角色的修改。”
这么说工厂的那三个兄弟都违反了开闭原则?
  • 打赏
  • 举报
回复
工厂方法模式并未能完全避免违反开闭原则啊~ 难道谁跟你说它没有违反开闭原则么? - - 工厂方法只是实现了对产品角色创建的封装,避免了工厂角色内部违反开闭原则~(简单工厂模式并未做到这一点~) 引用一句话来说明这个问题:“在工厂方法模式中,要么将判断逻辑留在抽 象工厂角色中,要么在客户程序中将具体工厂角色写死。而且产品 对象创建条件的改变必然会引起工厂角色的修改。”

62,623

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧