我有一位同事告诉我,他曾经为一家公司工作,该公司的政策是在代码中从不拥有条件(“if”和“switch”语句)并且他们让代码中的所有决定使用多态和(我猜)其他一些OO原则。
我有点理解这背后的原因,让代码更干,更容易更新,但我正在寻找对这个概念的更深入的解释。或者它可能是更通用的设计方法的一部分。
如果任何人有任何资源或愿意解释甚至有更多与此相关的条款我可以用来找到更多的答案,我将非常感激。
我发现one question on SO有点相关,但我不熟悉C ++,所以我不太了解那里的答案。
(我不是OO guru btw,但我可以管理)
我最熟悉PHP,在那之后我更喜欢那些使用这些语言的信息。
更新:我会向我的同事询问有关他的确切含义的更多信息。
2015年更新:经过多年的编程经验,我现在看到这个政策的目的可能是阻止程序员通过在某些地方添加条件(if语句)来随意添加功能。扩展软件的更好方法是使用继承和多态来扩展软件的"Open/Closed principle"。我强烈怀疑这项政策是否对所有条件都非常严格,因为如果没有它们,就很难完全实现。
答案 0 :(得分:51)
Anti-IF Campaign网站上有一些资源,例如this article。
我认为这是一个程度问题。条件并不总是坏的,但它们可能(并经常被)滥用。
其他想法(一天后)
Refactoring: Improving the Design of Existing Code是关于这个主题(以及许多其他人)的一个很好的参考。它涵盖Replace Conditional with Polymorphism。网站上还有一个新的Replace Conditional with Visitor。
我重视简单性和single responsibility,而不是删除所有if
语句。这三个目标经常重合。支持cyclomatic complexity指标的静态分析工具可以快速指出嵌套或串行条件的代码。 if
语句可能会在重构后保留,但可以分解为更小的方法和/或多个类。
更新:Michael Feathers撰写了一篇关于Unconditional Programming的文章。
这是一个热门话题:Phil Haack Death to the IF statement!
答案 1 :(得分:10)
经过几年的编程后,我回到了自己的问题,我现在明白了这个问题。
Sandi Metz的一个很好的演讲中,她将一个非常多毛的if语句重构为一些不那么毛茸茸的东西:https://www.youtube.com/watch?v=8bZh5LMaSmE
答案 2 :(得分:7)
我阅读了您链接的帖子,似乎他们主要讨论的是在类中删除对条件的需求,而不是与所有代码混淆。这个想法是,如果你需要检查对象的状态(使用条件)来确定它是否具有某些功能,那么实际上你有两个对象(一个支持功能,一个不支持),应该将它们定义为两个相关的课程。
答案 3 :(得分:6)
我有一位同事告诉我他曾经为一家公司工作过 作为一项政策,永远不会有条件(“如果”和“切换” 在代码中,他们让所有的决定 使用多态性和(我猜)其他一些OO完成代码 原理
我认为你的同事误解了某些东西或用错误的词语来解释它。 而你无法完全避免条件陈述。
有一件事要说:OOP中if语句的激增可能是编程错误的症状。一些例子:
不要使用if来检查函数的返回值,就像旧的C风格编程一样:
int ret = some_func();
if (ret != null)
//do something
这在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
}
有时,语句扩散与糟糕的设计有关。请考虑Java中的以下示例:
BaseClass base;
if (base instanceof DerivedClassOneFromBase){
DerivedClassOneFromBase d = (DerivedClassOneFromBase)base;
d.methodOne();
}else if (base instanceof DerivedClassOneFromBase){
DerivedClassTwoFromBase d = (DerivedClassTwoFromBase)base;
d.methodTwo();
}
这是错误的if语句的另一个例子,可能与糟糕的设计有关。如果两个派生对象在它们的基类BaseClass中定义了一个公共方法,那么你可以调用该方法而不是检查它们的具体类型并转换它们:
base.commonMethod();
答案 4 :(得分:4)
有时候方法中的条件是坏的,因为它们表明你只是在一个方法中执行多个函数或多个类型的方法。
如果您有一个名为Automobile的类和Carlass和Bike等子类,以及如下方法:
drive(Automobile a)
if (a.isCar)
// do stuff
else if (a.isBike)
// do stuff
你最喜欢做错事。即使它不是基于类型的开关,也常常是错误的。如果该方法根据某个变量执行多个函数,那么它通常会尝试执行多个操作,并且可能应该分成多个方法。
例如:
save(Car c)
if (c is new)
// do some stuff
else if (c is old)
// do some stuff
可能会被分解为保存和更新,因为它们是两个不同的功能。虽然它确实依赖。
完全禁止if语句是愚蠢的,因为它们有许多有效的用例。
答案 5 :(得分:0)
避免条件并不一定意味着您需要通过多态或继承来完成它,例如:
您有3个不同的文件夹来存储上传的图片,上传的视频和上传的pdf
您可以将代码编写为:
uploadMedia(mediaType){
if(mediaType == images){
uploadTo("myProject/images");
}else if(mediaType == videos){
upoloadTo("myProject/videos);
}else if(mediaType == pdf){
uploadTo("myProject/pdf");
}
}
人们可能使用的另一种选择是switch-case:
uploadMedia(mediaType){
switch(mediaType){
case : images
uploadTo("myProject/images");
break;
case : videos
uploadTo("myProject/videos");
break;
case : pdf
uploadTo("myProject/pdf");
break;
}
}
但是你可以通过使用像dictionary / hashmap / json这样的东西完全避免条件语句(取决于你使用的任何东西):
例如:
HashMap<String,String> mediaMap = new HashMap<>();
mediaMap.put("images","myProject/images");
mediaMap.put("videos","myProject/videos");
mediaMap.put("pdf","myProject/pdf");
//mediaType can be images/videos/pdf same as keys of mediaMap
uploadMedia(mediaType){
uploadTo(mediaMap.get(mediaType));
}
这是一种伪代码,因此可能存在语法错误,但总的来说这个概念也有助于避免条件。还可以减少代码行。