如果没有编程(基本上没有条件)

Nie*_*Bom 65 oop polymorphism conditional

我有一位同事告诉我,他曾经为一家公司工作,该公司的政策是在代码中永远不会有条件("if"和"switch"语句)并且他们让代码中的所有决策都使用多态性和(我猜)其他一些OO原则.

有点理解这背后的原因,让代码更干,更容易更新,但我正在寻找对这个概念的更深入的解释.或者它可能是更通用的设计方法的一部分.

如果任何人有任何资源或愿意解释甚至有更多与此相关的术语我可以用来找到更多的答案,我将非常感激.

我发现一个关于SO的问题有点相关但我不熟悉C++,所以我不太了解那里的答案.

(我不是OO guru btw,但我可以管理)

我最熟练的PHP,在那之后,我更喜欢那些使用这些语言的信息.

更新:我会问我的同事有关他的确切含义的更多信息.

2015年更新:经过多年的编程经验,我现在看到这个策略的目的可能是阻止程序员通过在某些地方添加条件(if语句)来随意添加功能.扩展软件的更好方法是使用"开放/封闭原则",其中使用继承和多态来扩展软件.我强烈怀疑这项政策是否对所有条件都非常严格,因为如果没有这些条件,这种政策就很难完全实现.

Tru*_*ill 56

反IF活动网站上有一些资源,例如本文.

我认为这是一个程度问题.条件并不总是坏的,但它们可能(并经常被)滥用.

额外的想法(一天后)

重构:改进现有代码的设计是这个主题(以及许多其他主题)的一个很好的参考.它涵盖了用多态性替换条件.网站上还有一个新的替换条件与访客.

我重视删除所有陈述的简单性和单一责任if.这三个目标经常重合.支持圈复杂度度量的静态分析工具可以快速指出嵌套或串行条件的代码.这些if陈述可能仍然在重构后,但可以分解为更小的方法和/或多个类.

更新: Michael Feathers写了一篇关于无条件编程的文章.

这是一个热门话题:Phil Haack on the Death对IF声明!

  • 我认为从Google Tech Talks中包含有关此原则的视频也很重要:https://www.youtube.com/watch?v = 4F72VULWFvc (3认同)

Nie*_*Bom 14

经过几年的编程后,我回到了我自己的问题,我现在的理解情况要好一些.

Sandi Metz有一个很好的演讲,她将一个非常毛茸茸的if语句重构为一些不那么毛茸茸的东西:https://www.youtube.com/watch?v = 8bZh5LMaSmE


Hei*_*bug 7

我有一位同事告诉我,他曾经为一家公司工作,该公司的政策是在代码中永远不会有条件("if"和"switch"语句)并且他们让代码中的所有决策都使用多态性和(我猜)其他一些OO原则.

我认为你的同事误解了某些东西或用错误的词语来解释它.而你无法完全避免条件陈述.

有一件事要说:OOP中if语句的激增可能是编程错误的症状.一些例子:

不要使用if来检查函数的返回值,就像旧的C风格编程一样:

int ret = some_func();
if (ret != null)
   //do something
Run Code Online (Sandbox Code Playgroud)

这在C代码中是典型的,但是使用OOP应该使用异常:

try{
    do_something();
}catch(Exception e){
    e.printStackTrace(); //why I was not able to do something
    handle(e); //there is something else I could do to handle the occurred error
}
Run Code Online (Sandbox Code Playgroud)

有时,如果声明扩散与糟糕的设计有关.考虑Java中的以下示例:

BaseClass base;
if (base instanceof DerivedClassOneFromBase){
    DerivedClassOneFromBase d = (DerivedClassOneFromBase)base;
    d.methodOne();
}else if (base instanceof DerivedClassOneFromBase){
    DerivedClassTwoFromBase d = (DerivedClassTwoFromBase)base;
    d.methodTwo();
}
Run Code Online (Sandbox Code Playgroud)

这是糟糕的if语句的另一个例子,可能与糟糕的设计有关.如果两个派生对象在其基类BaseClass中定义了一个公共方法,那么您可以调用该方法而不是检查它们的具体类型并将它们转换为:

base.commonMethod();
Run Code Online (Sandbox Code Playgroud)

  • @Renato Gama:是例外情况稍微慢一点,但重点是他们是例外.他们不应该控制流量决策结构,而是处理偶然的​​错误. (5认同)

小智 7

我阅读了你链接的帖子,似乎他们主要讨论的是在一个类中删除对条件语的需要,而不是与一般的所有代码混淆.这个想法是,如果你需要检查对象的状态(使用条件)来确定它是否具有某些功能,那么实际上你有两个对象(一个支持功能,一个不支持),应该将它们定义为两个相关的课程.


小智 5

有时,方法内部的条件是不好的,因为它们表明您只是在一个方法中执行多个函数或多个类型的方法。

如果您有一个名为Automobile的类以及诸如Car和Bike的子类,以及诸如以下的方法:

drive(Automobile a)
   if (a.isCar)
      // do stuff
   else if (a.isBike)
      // do stuff
Run Code Online (Sandbox Code Playgroud)

您最有可能做错事。即使它不是基于类型的开关,也经常会出错。如果该方法根据某个变量执行多种功能,则它经常尝试做的事情不只一件事,并且可能应分为多种方法。

例如:

save(Car c)
   if (c is new)
      // do some stuff
   else if (c is old)
      // do some stuff
Run Code Online (Sandbox Code Playgroud)

由于它们是两个不同的功能,因此有可能分解为保存和更新。虽然这取决于。

完全禁止语句是否愚蠢,因为它们有许多有效的用例。