[讨论] 如何区别和理解理解设计模式 ?
学习设计模式已经有一段时间了,但经常还是会很困惑。看书上的代码会发现很多不同的设计模式的代码结构非常相似。比如 Bridge 和 Strategy 。。。
既然是一个讨论贴,那我就先抛砖引玉,希望各位牛人赐教。。
设计模式就是我们设计过程中经常出现的一些相同的情景的解决方案。它也严格遵循设计原则,几乎所有的设计模式都遵循封装变化的原则,个人觉得GOF队设计模式的分类也是根据封装变化的不同来进行的分类,创建型模式封装的是对象的创建的变化,结构型模式封装的是结构的变化,而行为型模式封装的是行为的变化。
对于每个具体的模式区别则在于意图,看到网上有很多人写工厂方法模式和抽象工厂模式的区别,水平参差不齐,有的直接就从树上拷段代码,然后对着代码的结构来分析两者的区别。这样的分析对于初学而又迷惑的人来说非常的不好。
我这只是个水帖,希望大家多来点口水,不要吝惜。。。。
开发中尝到甜处了,嘿嘿
只有对设计模式了熟于心,才会恰当的用。
厉害 38 楼 xiaobin268 2008-11-16 一看就晕的人飘过 39 楼 sea7 2008-11-16 太郁闷了,发这个帖子是希望大家能有一个讨论,并不是什么希望别人给自己提意见如何学习设计模式的帖子,但有些人却一直在给我提着各种建议
晕。。。
40 楼 sea7 2008-11-16 tianmo2008 写道jeff.chuh 写道tianmo2008 写道这几天看书,工厂方法确实很不好理解,感觉没有必要,我的理解是引进工厂的目的之一是要是要隐藏掉new,但在工厂方法里,实现了工厂接口的具体工厂类自身也是要new的,这样,为什么不直接去new一个产品呢?而且和抽象工厂对比,我觉得工厂方法是定位在一个产品应该对应一个工厂类的,这样的话,没添加一个产品就得有对应的一个工厂,还得new一个工厂,这样还不如直接用产品接口,然后new一个具体产品不是更直观吗?工厂方法和接口感觉不到有什么优势.
你是没发现工厂用到什么地方,
当然对于ArrayList在代码里你可以到处new,
因为ArrayList的实现是稳定的,不需要你实现一个MyArrayList,
但是有些情况不一样,
比如有个FileLogger,从名字看出它是向文件输出log的实现类,
但你并不能保证你做好的项目以后不会变成向DB输出log,
这时你又实现了DBLogger,这时你发现FileLogger被new到各个地方,
你不得不一个个都替换成DBLogger。
而如果使用工程的话,你只需要修改工厂的实现就可以了,甚至你工厂是读取配置文件得到FileLogger的,
那么你只需要修改配置文件就可以了。
至于接口,你可以找找为什么要面向接口编程,这样做可以给你带来什么。
宏光点来看工厂模式的话,我是可以理解工厂的优势的,但现在是在工厂模式里面细分简单工厂、工厂方法和抽象工厂的时候,我个人觉得工厂方法在简单工厂和抽象工厂之间成了鸡肋,简单工厂和抽象工厂我都可以找到他们的应用场合,但工厂方法我却找不到,因为我目前接触的需求,要么就直接用简单工厂了事(尤其在配合反射的情况下),要么就直接分类后用抽象工厂,而没有考虑工厂方法的地方,所以觉得工厂方法很不好理解。
注意,我只是冲着工厂方法,而不是冲着整个工厂模式。
有这样一个case,现在你需要有一个生产某种品牌电脑的factory,请问你会使用简单工厂吗?
如果你使用简单工厂,那要是有一天有一个新的品牌的电脑呢??这个时候你需要怎么办??
41 楼 sea7 2008-11-16 zcclark 写道建议多看看Spring的代码,了解一下IOC,你会对工厂模式有更深的理解。
而且Spring写的代码质量也很高。
spring的源码,真的没有怎么看,但对于IOC还是比较了解的,不过我觉得也许叫做DI会更合适 42 楼 H_eaven 2008-11-17 sea7 写道tianmo2008 写道jeff.chuh 写道tianmo2008 写道这几天看书,工厂方法确实很不好理解,感觉没有必要,我的理解是引进工厂的目的之一是要是要隐藏掉new,但在工厂方法里,实现了工厂接口的具体工厂类自身也是要new的,这样,为什么不直接去new一个产品呢?而且和抽象工厂对比,我觉得工厂方法是定位在一个产品应该对应一个工厂类的,这样的话,没添加一个产品就得有对应的一个工厂,还得new一个工厂,这样还不如直接用产品接口,然后new一个具体产品不是更直观吗?工厂方法和接口感觉不到有什么优势.
你是没发现工厂用到什么地方,
当然对于ArrayList在代码里你可以到处new,
因为ArrayList的实现是稳定的,不需要你实现一个MyArrayList,
但是有些情况不一样,
比如有个FileLogger,从名字看出它是向文件输出log的实现类,
但你并不能保证你做好的项目以后不会变成向DB输出log,
这时你又实现了DBLogger,这时你发现FileLogger被new到各个地方,
你不得不一个个都替换成DBLogger。
而如果使用工程的话,你只需要修改工厂的实现就可以了,甚至你工厂是读取配置文件得到FileLogger的,
那么你只需要修改配置文件就可以了。
至于接口,你可以找找为什么要面向接口编程,这样做可以给你带来什么。
宏光点来看工厂模式的话,我是可以理解工厂的优势的,但现在是在工厂模式里面细分简单工厂、工厂方法和抽象工厂的时候,我个人觉得工厂方法在简单工厂和抽象工厂之间成了鸡肋,简单工厂和抽象工厂我都可以找到他们的应用场合,但工厂方法我却找不到,因为我目前接触的需求,要么就直接用简单工厂了事(尤其在配合反射的情况下),要么就直接分类后用抽象工厂,而没有考虑工厂方法的地方,所以觉得工厂方法很不好理解。
注意,我只是冲着工厂方法,而不是冲着整个工厂模式。
有这样一个case,现在你需要有一个生产某种品牌电脑的factory,请问你会使用简单工厂吗?
如果你使用简单工厂,那要是有一天有一个新的品牌的电脑呢??这个时候你需要怎么办??
简单工厂加反射,很强大.
43 楼 H_eaven 2008-11-17 简单工厂封装new XXX()到一个地方,便于修改.
工厂方法封装new XXX()到一个地方,便于扩展. 44 楼 sea7 2008-11-17 H_eaven 写道sea7 写道tianmo2008 写道jeff.chuh 写道tianmo2008 写道这几天看书,工厂方法确实很不好理解,感觉没有必要,我的理解是引进工厂的目的之一是要是要隐藏掉new,但在工厂方法里,实现了工厂接口的具体工厂类自身也是要new的,这样,为什么不直接去new一个产品呢?而且和抽象工厂对比,我觉得工厂方法是定位在一个产品应该对应一个工厂类的,这样的话,没添加一个产品就得有对应的一个工厂,还得new一个工厂,这样还不如直接用产品接口,然后new一个具体产品不是更直观吗?工厂方法和接口感觉不到有什么优势.
你是没发现工厂用到什么地方,
当然对于ArrayList在代码里你可以到处new,
因为ArrayList的实现是稳定的,不需要你实现一个MyArrayList,
但是有些情况不一样,
比如有个FileLogger,从名字看出它是向文件输出log的实现类,
但你并不能保证你做好的项目以后不会变成向DB输出log,
这时你又实现了DBLogger,这时你发现FileLogger被new到各个地方,
你不得不一个个都替换成DBLogger。
而如果使用工程的话,你只需要修改工厂的实现就可以了,甚至你工厂是读取配置文件得到FileLogger的,
那么你只需要修改配置文件就可以了。
至于接口,你可以找找为什么要面向接口编程,这样做可以给你带来什么。
宏光点来看工厂模式的话,我是可以理解工厂的优势的,但现在是在工厂模式里面细分简单工厂、工厂方法和抽象工厂的时候,我个人觉得工厂方法在简单工厂和抽象工厂之间成了鸡肋,简单工厂和抽象工厂我都可以找到他们的应用场合,但工厂方法我却找不到,因为我目前接触的需求,要么就直接用简单工厂了事(尤其在配合反射的情况下),要么就直接分类后用抽象工厂,而没有考虑工厂方法的地方,所以觉得工厂方法很不好理解。
注意,我只是冲着工厂方法,而不是冲着整个工厂模式。
有这样一个case,现在你需要有一个生产某种品牌电脑的factory,请问你会使用简单工厂吗?
如果你使用简单工厂,那要是有一天有一个新的品牌的电脑呢??这个时候你需要怎么办??
简单工厂加反射,很强大.
也许这样是可以实现,但你是否想到性能,反射必须会影响性能,而此时使用工厂方法则更为恰当,我们不只是要解决问题,而是要用最合理的方式解决问题. 45 楼 sea7 2008-11-17 H_eaven 写道版主把这贴给删除了,
发错了.
不明白你的意思???
46 楼 wcleye 2008-11-17 设计模式 个人觉得没必要学,记得前几个月我还不知道它是什么东西,但是整天在同事口里听到它,后来找来资料一看,原来这模式在项目中大部分都用过,只是不知道它的专业术语而已,现在看到有人整天把设计模式挂在嘴边,我不想多说什么,模式重在理解和实践中的体会,难道照着书本写几个例子就能弄懂设计模式吗?
时机到了,自然就懂了.. 47 楼 tibetjungle 2008-11-18 Ivan_Pig 写道书看了有两遍,感觉还是很肤浅。
我直到项目开发,才体会到设计模式的用途,感觉看书看不出什么来。
正解啊。
另外,gof书上的那些代码是经典,但不是说在项目里用各种语言去实现。实际应用中还是可以变通一下的。不要太教条! 48 楼 yunhaifeiwu 2008-11-19 sea7 写道H_eaven 写道sea7 写道tianmo2008 写道jeff.chuh 写道tianmo2008 写道这几天看书,工厂方法确实很不好理解,感觉没有必要,我的理解是引进工厂的目的之一是要是要隐藏掉new,但在工厂方法里,实现了工厂接口的具体工厂类自身也是要new的,这样,为什么不直接去new一个产品呢?而且和抽象工厂对比,我觉得工厂方法是定位在一个产品应该对应一个工厂类的,这样的话,没添加一个产品就得有对应的一个工厂,还得new一个工厂,这样还不如直接用产品接口,然后new一个具体产品不是更直观吗?工厂方法和接口感觉不到有什么优势.
你是没发现工厂用到什么地方,
当然对于ArrayList在代码里你可以到处new,
因为ArrayList的实现是稳定的,不需要你实现一个MyArrayList,
但是有些情况不一样,
比如有个FileLogger,从名字看出它是向文件输出log的实现类,
但你并不能保证你做好的项目以后不会变成向DB输出log,
这时你又实现了DBLogger,这时你发现FileLogger被new到各个地方,
你不得不一个个都替换成DBLogger。
而如果使用工程的话,你只需要修改工厂的实现就可以了,甚至你工厂是读取配置文件得到FileLogger的,
那么你只需要修改配置文件就可以了。
至于接口,你可以找找为什么要面向接口编程,这样做可以给你带来什么。
宏光点来看工厂模式的话,我是可以理解工厂的优势的,但现在是在工厂模式里面细分简单工厂、工厂方法和抽象工厂的时候,我个人觉得工厂方法在简单工厂和抽象工厂之间成了鸡肋,简单工厂和抽象工厂我都可以找到他们的应用场合,但工厂方法我却找不到,因为我目前接触的需求,要么就直接用简单工厂了事(尤其在配合反射的情况下),要么就直接分类后用抽象工厂,而没有考虑工厂方法的地方,所以觉得工厂方法很不好理解。
注意,我只是冲着工厂方法,而不是冲着整个工厂模式。
有这样一个case,现在你需要有一个生产某种品牌电脑的factory,请问你会使用简单工厂吗?
如果你使用简单工厂,那要是有一天有一个新的品牌的电脑呢??这个时候你需要怎么办??
简单工厂加反射,很强大.
也许这样是可以实现,但你是否想到性能,反射必须会影响性能,而此时使用工厂方法则更为恰当,我们不只是要解决问题,而是要用最合理的方式解决问题.
反射 在框架中无处不在。spring struts 等等都使用了反射。到目前为止,反射对性能的影响,也没怎么考虑了。
服务器,不会还用上几代的吧
49 楼 xixix2004 2008-11-19 我学习设计模式的方法是不急着去看代码,而是先理解他的定义,在网上查找此设计模式的使用场合.因为设计模式而言,本身就应该是脱离代码层面的.
但是学习了一段时间以后我就放弃,因为说实在的,实在没有意义.为了设计模式而设计模式不可取. 50 楼 dxiao2 2008-11-20 我觉得看看书 了解下设计模式的大概几个就行了
然后在自己工作中设计类的时候 想想自己的需求和目的 然后套套设计模式
多用用几次就自然而然全理解了 51 楼 410228573 2008-11-21 我是个新入行者,对设计模式也是了解不理解,因为没用过,或者说没看过别人项目里面使用的设计模式,如果自己用过或者说是见过的话我自信自己能够理解。实践出真知一点不错。 52 楼 daweiangel 2008-11-21 sea7 写道woods 写道我对模式的感觉:
1.设计模式能给你一个设计的起点,然后随后慢慢根据需要重构出适合你的项目的设计.
2.给了你一个交流的语境.(讨论时候:"恩恩 我觉得这里需要个strategy...")
3.没必要非得死靠这是某某模式,实际使用往往是某几种模式的综合
4.设计模式的核心感觉:封装变化,抽象行为,多用组合:P
同意
en tongyi 53 楼 daweiangel 2008-11-21 410228573 写道我是个新入行者,对设计模式也是了解不理解,因为没用过,或者说没看过别人项目里面使用的设计模式,如果自己用过或者说是见过的话我自信自己能够理解。实践出真知一点不错。
你都入行了我还再门前徘徊那,羡慕! 54 楼 狂放不羁 2008-11-23 我觉得设计模式容易理解,但是用好很难。