论坛首页 Java企业应用论坛

对于OCP原则的困惑

浏览 44437 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-09-24  
ajoo 写道
raimundox:
A a = AFactory.getInstance();


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

吗?


静态工厂根本就不是对应ocp原则的。它的目标是向内的,是封装内部的实现细节。对外部,它还是一个具体的依赖,和new AFactory()区别不大。


现在讨论的问题是把B换成C,那么我可以
AFactory.getInstance() {
  return new B();
}

->

AFactory.getInstance() {
  return new C();
}

这样Client ocp了吧?
Client并不负责自己来拿那个类,只是告诉它有一类给你用,然后告诉它怎么拿。
我知道静态工厂不指向ocp,我只说这样可以这样简单的实现一个ocp
0 请登录后投票
   发表时间:2004-09-24  
另外当需要根据输入选择的时候,这个处理也是AFactory做的,而不是client做。
0 请登录后投票
   发表时间:2004-09-24  
扩展而不是改变。如果你只考虑客户,你既没扩展,也没改变,因为你把这个变化的scope挪出去了,根本就没有解决问题,而是回避了问题。

而真正解决问题的地方,AFactory内部还是要修改,而不是扩展。

所以这没有实现ocp,仅仅是封装。

当然,oo原则并不仅仅是ocp。
0 请登录后投票
   发表时间:2004-09-24  
mm, 也许我的批评不对。
这也许也可以算做是ocp吧?不确定。

不过,至少,你这个service locator方法应对变化的能力远小于基于注射的ioc。复杂度也差不多。
0 请登录后投票
   发表时间:2004-09-24  
我还是:
千言万语离不开一句话:谨慎使用工厂模式。
0 请登录后投票
   发表时间:2004-09-24  
ajoo 写道
mm, 也许我的批评不对。
这也许也可以算做是ocp吧?不确定。

不过,至少,你这个service locator方法应对变化的能力远小于基于注射的ioc。复杂度也差不多。


sigh ~~~,ajoo兄,我并没有说这是一个完美的方案,我只是在说一个问题,就是ocp有scope的,AFactory承担了Client的变化的部分,于是Client满足了ocp,我的意思是说,想做好ocp,一个关键就是找一个东西,来替你承担变化的风险,Factory只是一个例子。
但是当考虑整个系统范围的ocp,Factory可能会引来额外的复杂,采用injection就是一个很好的办法。
赫赫,ajoo兄,现在成了ioc的忠实拥趸了,可曾记得3,4月间在冰云的blog上那场关于ioc的争论?里面的raimundo就是小弟我了:)
0 请登录后投票
   发表时间:2004-09-24  
没有什么现在成为xxx。

几年前我就在使用这种注射技术,只不过不知道这个名字而已。

和冰云的讨论,我的观点和在这里没有任何变化,我始终赞同ioc,认为那是必然的设计方法。但是我反对把ioc庸俗化成容器编程。ioc和容器没关系,和配置文件更没关系。并不是用了pico/spring就ioc了,相反,很多用这些容器的人背离了ioc的本意,把这些容器当作可以直接依赖的库使用了。
我反对的是这种误解。

要知道,最好的使用容器的方法就是保持对容器的无知。容器是为你的oo设计服务的,你不应该为容器服务。

factory主要不是复杂度的问题。它和ioc比较的话,ioc是真正去掉了不应该有的依赖。而factory只不过把依赖从一个地方转移到另一个地方。但是无论如何,依赖还在。

当你需要的服务和你自己的逻辑是正交的时候,绝对不应该使用factory。
0 请登录后投票
   发表时间:2004-09-25  
Factory Pattern 當然是 ocp 的一種形式。 ocp 並不是說要去除依賴,而是要 closed for modification ,但真正的變化是 close 不了的,所以其隱含的就是要封裝變化,移出變化。不論是用 ioc 或是用 Factory ,都是將建立物件的變化加以封裝並移出,一個是到容器上,一個是到 Factory 中。

雖然很多使用 Factory 的地方其實用 ioc 會更適合,但 Factory 仍有其適用的地方。當使用的物件是根據 runtime 的決定而有不同時,封裝這一層變化就適合使用Factory ,當然 Factory 中再配合 ioc 會更好。 ioc 比較適合較靜態的變化,也就是部署時的動態性,而 Factory 適合 runtime 時的動態性。當然,不是互斥的,應該說是其重點不同。

當然,把 ioc 當成 Factory 來依賴不是個好用法。
0 请登录后投票
   发表时间:2004-10-10  
只要文档写得清晰自明,
程序可读性好,

都可以。

A a = new A();
D d = new E();
在软件中出现根本不是灾难来临的象征

研究这个模式那个标准,
不如把时间成本投入API优化,问题领域研究,
客户价值分析 , 团队培训,自动化工具等其他有意义的地方。
0 请登录后投票
   发表时间:2004-10-10  
zingers 写道
只要文档写得清晰自明,
程序可读性好,

都可以。

A a = new A();
D d = new E();
在软件中出现根本不是灾难来临的象征

研究这个模式那个标准,
不如把时间成本投入API优化,问题领域研究,
客户价值分析 , 团队培训,自动化工具等其他有意义的地方。


你要这么说就没意思了,那我们研究这个技术那个工具,还不如炒楼花来钱快呢。既然讨论这个问题,就不是在考虑它的“意义”,要是什么都想到“意义”,我们还不如估算一下抢银行的风险利润比。
0 请登录后投票
论坛首页 Java企业应用版

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