论坛首页 Java企业应用论坛

对于OCP原则的困惑

浏览 44440 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-11-02  
引用
无论你用什么方法,你总有一个地方去存放你的规则,

这话不是没说一样?
无论我怎么设计, 该做的功能总要通过代码做出来, 不可能一念咒就成.

但是同样的东西放在什么地方就是学问了.

你那么长的帖子, 我也没看明白你要说什么.

你说
引用
你以为我就不能新写一个工厂来支持新的I3乐?!!!


很好, 请你把你的想法写成代码, 我们看看好么?

关键是, 新增加了新的功能, 不要修改过去的已经工作的代码.
0 请登录后投票
   发表时间:2004-11-03  
swing 写道

我的问题是,当你去实现一个MyReader时,你是如何去实例化的,这是时候你是不是总是使用new MyReader的?还是说,你会在情况变复杂的时候,使用一个工厂之类的东西去封装掉你自己的Reader实现的实例化?


这个问题已经讨论过了,我以前也比较坚持new不能随便使用的观点,然而这样的观点带着强烈的理想主义,在实际项目中一味坚持它是得不偿失的,其实更准确一点的说法是适用,而不是过渡使用。
如果使用了Spring,或者pico等容器,那么大部分的对象实例的生成都可以通过容器来生成并组装。然而,并不是所有的项目都会使用这些容器,也不是所有的对象都能够通过bean来生成。这里就给很多人一个选择的余地。如果说仅仅为了去掉“new”而大幅增加原本简单的设计,那么就很值得斟酌了。
0 请登录后投票
   发表时间:2004-11-03  
firebody,无论任何讨论,都是基于一个基础或者说环境的,我之所以有那样的问题,是基于前面的讨论。
这和说话是一样的,同样是“好的”这样一个词,它放在不同语境是有不同含义的,你不要断章取义。
我想谁都不会说,你不应该使用new,
而是说,在那样的环境下,使用new不能达到你解耦的目的,请注意这里的目的,如果根本没什么必要的话,我才不去做那么多事情,比如就上面那个例子,条件许可我就尽管可以new MyReader好乐,而且我也说了,那样说是有点较真的,只是提供个参考下罢了。

to ajoo  同样道理,请不要断章取义,你所引用的两句话,之所以那么说,是有语境的,而且你要我实现给你看,实在是让我觉得你是在争辩而不是讨论问题,
下面是我的实现,比较简略的:
public class Factory {
     public static I getInstance() {
               return new I3();
    }
}
如果你看乐这段代码觉得可笑,那么你就该知道你的问题有多可笑乐。完全不考虑语境,不考虑我的话的前提条件,这样争论有什么意思?

最后,你自己也说:你那么长的帖子, 我也没看明白你要说什么.

那么请你不要理我好了,既然你没有明白我要说什么,为什么你还能对我的话有那么多好争的?你要说,那就说我没说清楚要说什么或者“不知所云”之类就完乐,一方面说你不明白我说什么,一方面又对我的话提出看法。

好了,我是没那么多时间精力好同你争乐,如果你能够心平气和地讨论讨论一些东西,那么咱们再说好乐。
0 请登录后投票
   发表时间:2004-11-04  
说着说着就带上气了? 至于么? 不说技术, 要是讨论没有点讨论的度量, 动不动就着急上火的, 那倒是最好别开口了.

看看你的代码吧

public class Factory { 
  public static I getInstance(); { 
    return new I3();; 
  } 
} 

那么, 你原来的使用I的那个类是什么样的, 能给展示一下吗?

我现在理解的你的想法是这样的 (这就是我如果没看明白别人的意思的时候的办法, 说明我理解的对方意思, 让对方指出理解错误之处, 这没问题吧?):

class IClient{

  private final I i = IFactory.getInstance();;
  void f();{
    ....
    i.g();;
   ...
  }
}

你原来的IFactory的代码是:

class IFactory{
  static I getInstance();{return new I1();;}
}

你说如果你需要I2, 就改动IFactory成

class IFactory{
  static I getInstance();{return new I2();;}
}


当然, 如果你不是我理解的这样, 那就把我后面的忽略掉吧.

下面, 我说, 我有一个I3要使用. 你说你可以新建一个新的工厂:
public class Factory { 
  public static I getInstance(); { 
    return new I3();; 
  } 
} 

不过, 我不明白你这个新的工厂有什么用? 我要让IClient使用这个新的I3啊. 你难道不要或者改动IFactory或者改动IClient么?
无论如何, 你不是在为了新的功能改动原来已经工作得很好得代码?

还有, 你始终没有演示一下你怎么根据用户动态得输入来选择让IClient使用I1或者I2, 象这样:

if(user_input_feature_2);
  return new IClient(new I2(););;
else
  return new IClient(new I1(););;


或者, 如果IClient是个库, 我有两个互相独立的application, app 1有一个自己的I1, app2有一个自己的I2.
两个app都要用自己的这个I的实现来调用IClient.

你怎么用工厂来实现这个需求?
做一个核心的IFactory, 每多一个app就修改一下这个IFactory类?
0 请登录后投票
   发表时间:2004-11-04  
to ajoo
首先,我道歉,我应该允许别人曲解或者对我的话断章取义。

第二,我已经说乐,你是断章取义,自然你说的不是我说的意思。

第三,我是希望在这里少些对语言本身表达的争论,如果我发个帖子,需要另外再贴几个来解释,那实在太累乐(大家都累)。因此如果你不理解,那就简单说不理解好了,如果断章取义,那是容易引起不必要的争论的。

第四,既然到这里乐,我把我的话重新引用解释下:
引用
好了,如果你说,我这是在新的application里面一个新应用,你有新的客户端代码比如:
return new MyClass(new I3());

好嘛,你以为我就不能新写一个工厂来支持新的I3乐?!!!

请注意前面的“如果”,那是我新的工厂之所以那样写的前提。

第五,你的新问题,说我从来没有说我的工厂是如何实现的,这个实现我就不写乐,因为太显然。(这里如果你认为不是“显然”,那就算了)

第六,你可以参考这个来考虑我所说的工厂实现:
引用
其实对我来说,你写的:
引用:


1 if(...)
2 return new MyClass(new I1());
3 else return new MyClass(new I2());


我就是放在我的工厂里面的代码,你说说看有没有区别?

而且比你现在这样还好些,怎么说我要是增加乐I3,也只是修改工厂这一个地方而已,而你的代码如果(注意,是如果)散落在客户端各个地方,到时候还怎么改?好了,如果你的客户端只有一个地方有你上面那段代码,而且你是把它放在一个方法里面的,呵呵,你这就不算工厂乐?
我说你这是准工厂,相对工厂来说,它依赖实现细节,违反DIP原则,你还称之为ioc。

但是,我这么说,只是相对于你的实现而言,至于我是不是真的就这样来实现工厂,那我是看具体环境的,不一定是这样实现,这也是我不去强调工厂如何实现的原因,因为设计不是孤立存在的。

第七,我们这里讨论的一个大前提你忘了,如果脱离这个大前提,我觉得就没有必要讨论的,我们讨论的是OCP,不是说,如果不应用OCP代码就不能实现乐,实际上具体环境中是需要考虑度的,哪里需要,哪里不需要都是依具体环境而言,不分“对”或者“错”的。

第八,我上面只是解释乐部分,其实还有些话你断章取义的,因为是小方面,我就不一一解释乐。

第九,如果这样说,你还是持你前面的看法,那么你就说我表达能力太差好了,不需要再重新发表一次你的看法。
0 请登录后投票
   发表时间:2004-12-01  
OCP不是这么理解的.
Modification一般是由于不可预期的改变引起的.
Extension是由于可预期的改变引起的.
看看Eclipse的体系就知道什么是优秀的OCP设计了 
0 请登录后投票
   发表时间:2004-12-09  
"抽象写进代码,实现交给配置"
--我想这是原则们,框架们,容器们...所追求的效果
0 请登录后投票
   发表时间:2004-12-29  
引用

"抽象写进代码,实现交给配置"
--我想这是原则们,框架们,容器们...所追求的效果

这句话看上去太完美了,但作为一个民工我实在是不能理解什么是代码,什么是配置,不都你运行需要的程序?都是两个写在磁盘上的文件?好像一个是编译成什么叫class (java)的,一个不用编译就是xml(里面有点小错误在运行才知道)?.然后我又有个问题了:jvm好像是不认识xml的,他怎么混入那个java队伍的?哦,需要java去解析它.java怪不得大家都说ioc神奇了,一个混入java 队伍的"异类"却能魔术般的变化出各种各样的类的实例?怎么变的,看看ioc的各种实现,哇,原来是个facotry类,进口xml出口java的instance.俺就迷惑了上面有些个人反对工厂,怎么还一直在用ioc这个大工厂?再想想中国有句老话:眼不见为净!

大工厂就是好流行!大家都用,看看spring,pocontainer用的人真不少啊,可是好像每个人的语法配置都不一样,咱民工学个java已经很吃力了,还要学这个,实在...另外感觉这东西就象用上了windows上瘾,俺现在想换linux真教个吃力啊.这个ioc说是要减少依赖,俺咋觉得一用就依赖上了他呢?大厂就是牛,限制多多,俺自家的工厂多方便.配置好东东,千变万化的,可是xml这个东东查错实在是...咱有在eclipse里面java敲错了字还能立马查到.java编译器的规范还是统一的么.

另外说是ioc修改的少?偶咋没觉的:你改个配置,偶改个fatory,都一样么.说起测试?偶还快点,0.0001秒钟,什么移植方便?偶可是标准的java,一个jar文件就过去了,什么你的的ioc container 不兼容? 我只能偷着乐了.

说到客户调用,客户还得先学会container,你要要依赖他,什么container 要收费了<玩笑> 你的客户 , 
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics