锁定老帖子 主题:对于OCP原则的困惑
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2004-09-22
庄表伟 写道 我一开始就说过了。
当且仅当:一个类,有两个以上的用法时,才需要重构,为它加上interface。 请回答我最后的问题! |
|
返回顶楼 | |
发表时间:2004-09-22
庄表伟 写道 我一开始就说过了。
当且仅当:一个类,有两个以上的用法时,才需要重构,为它加上interface。 我觉得不是. 接口更多是需求方使用的. 比如, 如果你的模块需要从别的模块得到一些服务, 就设计接口. 弄ioc,或者从参数得到具体实现. 此时,具体类可能还根本不存在呢. |
|
返回顶楼 | |
发表时间:2004-09-22
firebody 写道 庄表伟 写道 我一开始就说过了。
当且仅当:一个类,有两个以上的用法时,才需要重构,为它加上interface。 请回答我最后的问题! 不要这么凶嘛,我又不打算跟你吵架:) firebody 写道 你敢说你设计的interface在项目进展中不用改动吗?
就是这句吧,听我来回答你。 我从来没有说过我的设计,不需要改动代码。 我只是说:“在n次修改以后,你的总代码数(第一次的代码数+每次修改改动的代码数)最小,那么你的设计就是最合理的。” 在出现两个接口之前,对于代码修改,一种情况是只修改类本身,一种是同时修改类和接口。在出现两个接口之后,代码修改的量是一样的。 那么总的来说,在只需要一个interface的时候,就不该使用interface。因为那样会增加代码修改的总量。 我说的清楚了吗? |
|
返回顶楼 | |
发表时间:2004-09-22
引用 一开始就设计接口,又何尝不可呢?难道一开始就设计接口就是过渡设计吗?
接口出来,就一定要工厂来支撑它的实例化吗? 我的设计思路的实施总是是伴随着实现我的抽象接口展开的,当然抽象接口的提取应该是具体-->抽象--->具体设计的过程。 其实爆发这么激烈的争论的缘由,看看我的原贴。还是因为一些用词的误会引起的。 就如同我上面提到的 一开始这个词,本来我想表明的意思是说在详细分析用例之后,以及作出相应的UML草图类层次推理之后,进入正式设计项目核心类层次结构的这个阶段,我指的开始就是指“项目正是进入设计实施'的阶段。后面为了强调我的这个观点;我还加了一句: 当然抽象接口的提取应该是具体-->抽象--->具体设计的过程。 但是,无奈,讨论的焦点还是引入到了interface的设计时机上来! 我想老庄误会我的一些词眼了! |
|
返回顶楼 | |
发表时间:2004-09-22
ajoo 写道 庄表伟 写道 我一开始就说过了。
当且仅当:一个类,有两个以上的用法时,才需要重构,为它加上interface。 我觉得不是. 接口更多是需求方使用的. 比如, 如果你的模块需要从别的模块得到一些服务, 就设计接口. 弄ioc,或者从参数得到具体实现. 此时,具体类可能还根本不存在呢. 我们讨论的情况是:都是自己的东西。不要自己给自己制造麻烦。 而你说的情况是,用人家的东西。但是如果是用人家的东西,人家提供给我什么,我就用什么,我有得选的吗? |
|
返回顶楼 | |
发表时间:2004-09-22
庄表伟 写道 Help youself!
1、设计的复杂程度,不是“离散”而是“连续”的。 2、设计的复杂度,不是静止的,而是生长的。 3、复杂度的生长,不是全面的,而是有一定方向的。 4、提前设计,就是在准确预计复杂度生长的方向的基础上做出的设计。 5、过度设计,就是在无法预计复杂度生长的方向的情况下,在每一个方向加入灵活性。 6、如果一个类,只有一种用法,而你再给他加上一个接口,那么在需求没有稳定之前,每次改动,你可能需要同时改两个以上的文件。 7、如果你通过配置文件来定义,那么改动工作就转移到了配置文件。 8、总而言之,如果你在需求没有稳定下来之前,搞出n多的层次,来隔离变化,非常有可能出现的情况就是:当变化来临,你不但没有隔离变化,而且需要同时更改n多的文件。 从一开始就设计接口,然后你就会不断的同时修改类和接口的文件。我并不认为这是一个省力的办法。只有当需要接口的信号明确出现时,才是使用接口的好时机。 容器装配对象的概念深入人心,并不是让自己更加费力的理由。 美学也不是。 有道理。 假如我的系统有一个DAO层和一个SERVICE层,DAO层为SERVICE层提供服务,SERVICE层为表示层提供服务。DAO层就不用接口了,只在SERVICE层用接口。DAO层也可以设计接口,但我觉得麻烦,一改就要改两个文件。 |
|
返回顶楼 | |
发表时间:2004-09-22
firebody 写道 就如同我上面提到的
一开始这个词,本来我想表明的意思是说在详细分析用例之后,以及作出相应的UML草图类层次推理之后,进入正式设计项目核心类层次结构的这个阶段,我指的开始就是指“项目正是进入设计实施'的阶段。后面为了强调我的这个观点;我还加了一句: 当然抽象接口的提取应该是具体-->抽象--->具体设计的过程。 但是,无奈,讨论的焦点还是引入到了interface的设计时机上来! 我想老庄误会我的一些词眼了! 我不是误会你的某些用词,而是你的这些用词之间,存在矛盾。 就按照你现在的解释来说,存在一个前期的,详细的设计,这种情况下,根本就是假设“设计将来不会再有大的改动了。”那么在你这样的设计情况下,一开始就有interface当然是正常的。 就像我前面说的:“提前设计,就是在准确预计复杂度生长的方向的基础上做出的设计。” 那么这样的前期详细设计,就存在这样一个问题:有经验的人就是提前设计,没经验的人“自以为”在提前设计,而实际上在过度设计。 这已经不是OO原则的争论了,而是软件工程的正统方法与敏捷开发方法之间的争论了。 |
|
返回顶楼 | |
发表时间:2004-09-22
ajoo 写道 庄表伟 写道 我一开始就说过了。
当且仅当:一个类,有两个以上的用法时,才需要重构,为它加上interface。 我觉得不是. 接口更多是需求方使用的. 比如, 如果你的模块需要从别的模块得到一些服务, 就设计接口. 弄ioc,或者从参数得到具体实现. 此时,具体类可能还根本不存在呢. 同意。很多时候设计接口只是因为各个模块要同步开工,用接口来约束一下各方的开发人员。 |
|
返回顶楼 | |
发表时间:2004-09-22
庄表伟 写道 我们讨论的情况是:都是自己的东西。不要自己给自己制造麻烦。 而你说的情况是,用人家的东西。但是如果是用人家的东西,人家提供给我什么,我就用什么,我有得选的吗? 自己的东西, 也会有分工. 除非你自己只有一个非常内聚的模块. 如果有分工, 就会有模块间的调用关系. 只要你写每个单独模块的时候忘记别的具体模块, 用接口来从外界接收实现就是了. 也就是说, 依赖抽象, 不要依赖具体. 这既保证了每个模块的单独测试能力, 也保证了以后替换其它实现的灵活性. 也没有预付任何复杂度. 关于别人的模块, 一样处理, 只有当前模块和其它模块的区别, 没有别人的模块和自己模块的区别. |
|
返回顶楼 | |
发表时间:2004-09-22
to:ajoo
说说模块之间,通过接口,而不是实际的对象进行通信的好处吧。 我自己就不说了,免得你说我是在打自己树的靶子。 另外先埋伏一句话在这里:“所有这些好处,不引入‘如果’,就无法成立。” |
|
返回顶楼 | |