论坛首页 Java企业应用论坛

对于OCP原则的困惑

浏览 44435 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-09-23  
ajoo 写道

其实,印证一下我那篇关于接口编程的公理游戏,
需求者用接口就可以ask no more。
服务者用接口就可以promise no more。


你的所谓公理:需求者用接口ask no more,服务者用接口promise no more。

大家可能看不大明白,我就用比较容易理解的方式翻译一下:接口定义要恰到好处。

这种公理大家可以随手拈来,并保证永远正确无误,举例:接口定义越恰当就越接近完美。
0 请登录后投票
   发表时间:2004-09-23  
firebody 写道
ajoo
I 服了 you

不过仔细看了你的辩驳,嘿嘿,我甘败下风。
跟你吵架,无异于找death。
以后,一见到你ajoo远远冲过来,我立马退避三舍。哈哈

然后他就会撞在一块豆腐上。 
0 请登录后投票
   发表时间:2004-09-23  
to:ajoo

我可还没服,只是今天有点忙,明天再回帖。
0 请登录后投票
   发表时间:2004-09-23  
我谈点看法吧:
  1、OCP原则并非天生就有的,是代码进化的结果
  2、实现OCP是以Interface为基础的,这里的Interface并非java的 interface,而是你组件的界面。
  3、设计组件并非一开始就直奔OCP的,而是曲折近似的达到OCP。也就是这个Interface是进化的结果,也是Open的基础
  4、有了Interface,你就可以有不同的实现,这就是close的表现
  5、OCP并非着重是否修改代码,而是着重你对原有环境的影响,这里分2:
    A、一个未在运行的系统,如何让改动代价最少
    B、一个在运行的系统,如何让改动不影响现有系统的运行。这也是OCP所关注的。
  6、并非OO才能实现OCP
0 请登录后投票
   发表时间:2004-09-23  
我觉得这种问题讨论的甚是无趣。就像<Remains of the Day> 里面那个Stevens,拿着尺子测量杆盘刀叉与餐桌距离。
0 请登录后投票
   发表时间:2004-09-23  
age0 写道
ajoo 写道

其实,印证一下我那篇关于接口编程的公理游戏,
需求者用接口就可以ask no more。
服务者用接口就可以promise no more。


你的所谓公理:需求者用接口ask no more,服务者用接口promise no more。

大家可能看不大明白,我就用比较容易理解的方式翻译一下:接口定义要恰到好处。

这种公理大家可以随手拈来,并保证永远正确无误,举例:接口定义越恰当就越接近完美。

随手拈来?照你这么说,ocp也可以说随手拈来,ioc我也是随手拈来的。都是很直觉化的东东。
两条平行线不相交你是否也觉得随手拈来?

正确无误不一定能够作为组成一个系统的基石,不一定具有实际操作性。
不知道你能否针对这两点给出反驳?
要不你随手拈来一个,我给你找毛病也行。

所谓“接口越恰当”如何如何,你要是拿来做公理,就有问题。
首先,接口的定义为何?是指interface吗?
其次,什么叫“恰当”? 你这句话的正确性仅仅建立在它的模糊性上,跟算命的差不多。这么主观性的形容词你也敢拿出来做公理?
0 请登录后投票
   发表时间:2004-09-24  
yhc0125 写道
我对OCP原则的困惑:

ocp原则的基本思想是对于扩展是开放的,对于更改是封闭的。该原则在java中的实现是通过接口完成的,可是在具体操作中功能的扩展是一定会出现变化的,这样怎么是对更改是封闭的呢?

比如说我定义了一个接口Interface A,他的一个实现class B,我在调用B来完成功能时这样做A temp = new B();

这样的话当我给他另外一个实现class C时,我的客户段代码还是要改变的:
A temp = new C();

这也不是封闭的呀?

以上是我的理解,请各位指教小弟一下


首先明确一点,并不是使用interface就一定可以实现ocp的,而且使用interface和达到ocp没有什么必然的联系。
就像你的例子,比如我写成这样:

  public interface A {
  }
  
  public class B implements A {
  }

  public class Client {

      public void someMethod(); {
           A a = new B();;
      }
  }


好,对someMehtod的而言,这并不是ocp的,因为当需要把B换成C的时候,代码仍然需要修改。那么怎么办?做一个小变化。

  public void someMethod(); {
    A a = getA();;
  }
  private A getA(); {
    return new B();;
  }


这个好一些,但是也不见得高明到哪里去。但是有一个变化,当需要把B换成C的时候,someMethod不变,但是getA()需要变化。这说明一个什么问题?ocp是有scope的,在这样的实现里,你可以说someMethod是ocp的,而getA不是!这就是我说的scope,那么我们期望的scope是什么?最基本的,一个class因该符合ocp,怎么办?一种简单的方法,静态工厂。
public void someMethod(); {
    A a = AFactory.getInstance();
  }


这样,Client这个代码自己就ocp了,而把变化的部分推给AFactory,说起来有点各扫门前雪式的推诿,但是就是这样。而且这样也符合另外一个oo原则,针对对变化封装。

好,现在一个class满足ocp了,但是我们希望整个系统满足ocp,怎么办?第一,将变化推给另外一个系统,第二,将变化从代码移到代码之外,也就是把配置从代码级变成xml或者别的什么。

其实这样可以发现,ioc container + 一定的设计,整个系统可以很容易的满足ocp,这也是ioc container流行的原因之一。
0 请登录后投票
   发表时间:2004-09-24  
age0 写道
只要使用了继承,出现了派生类,OCP原则都会被打破,无论你如何部署代码,显式创建派生类的代码都是无可避免的。

如果你一定要坚持OCP原则,首先必须坚持CARP原则,只有CARP原则成立的情况下才能达到OCP的效果。


不一定,最简单的一个例子

public abstract Example {
   private static String defaultImplClass =  "xxxx";

   public static Example getInstance(); {
      String implClass = System.getProperty("xxxxx");;
      try {
         return Class.forName(implClass);.newInstance();;
      } catch (Exception e); {
         return Class.forName(defaultImplClass);.newInstance();;
      }
   }
}


异常处理不完整,主要说这个意思。
0 请登录后投票
   发表时间:2004-09-24  
庄表伟 写道
为什么要隔离?
设计为什么就是“丑陋”的?

隔离、美丽,都要付出代价的,这些代价,究竟该不该付出,是需要考虑的。


庄,我觉得还是一句话,对变化封装,如果不变,或者变化的可能很小,封装、隔离就意义不大,这个封装、隔离就成为了负担。
0 请登录后投票
   发表时间:2004-09-24  
raimundox:
A a = AFactory.getInstance();


这就ocp了吗? 我看不见得。你直接依赖于AFactory这个具体类。
如果需求变化成:根据用户输入的不同,选择两个不同的A的实现类。你怎么办?
改成:
if(...);
  A a = Afactory1.getInstance();;
else
  A a = Afactory2.getInstance();;

吗?


静态工厂根本就不是对应ocp原则的。它的目标是向内的,是封装内部的实现细节。对外部,它还是一个具体的依赖,和new AFactory()区别不大。
0 请登录后投票
论坛首页 Java企业应用版

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