无编程(基本上没有条件)
我有一位同事告诉我,他曾经为一家公司做过工作,他们没有在代码中使用条件语句(“if”和“switch”语句),他们让代码中的所有决定都使用多态性和(我猜)一些其他的OO原则。
我有点理解这个背后的原因,让代码更干,更容易更新,但我正在寻找这个概念的更深入的解释。 或者,也许这是更一般的devise方法的一部分。
如果有人有这方面的资源,或者愿意解释,甚至有更多的相关条款,我可以用来find更多的答案,我会非常感激。
我在SO上发现了一个相关的问题,但是我对C ++不熟悉,所以我不太了解那里的答案。
(我不是OO大师顺便说一句,但我可以pipe理)
我是最擅长的PHP,之后Python,所以我更喜欢使用这些语言的信息。
更新:我会问我的同事更多的信息,他是什么意思。
更新2015年:经过多年的编程经验,我现在看到,这个政策的目的可能是防止程序员通过在某些地方添加条件语句(如果语句)以偶然的方式添加function。 扩展软件的一个更好的方法是使用软件通过inheritance和多态扩展的“打开/closures原则” 。 我强烈怀疑这个政策是否在所有条件下都是超严格的,因为如果没有这个政策,就很难完全走下去。
反IF运动网站上有一些资源,例如本文 。
我相信这是一个程度问题。 条件并不总是不好,但他们可能(并经常)被滥用。
另外的想法(一天之后)
重构:改进现有代码的devise是关于这个主题(和许多其他)的很好的参考。 它涵盖了用多态性replace条件 。 还有一个新的,在网站上用条件replace访问者 。
我重视简单和单一的责任去除所有if
语句。 这三个目标经常是一致的。 支持圈复杂性度量的静态分析工具可以快速地指出嵌套或串行条件的代码。 if
语句可能保留后重构,但可以分解成更小的方法和/或多个类。
更新:迈克尔羽毛写了一篇关于无条件编程的文章。
这是一个很受欢迎的话题:Phil Haack 死于IF声明 !
经过几年的编程,我回到了我自己的问题,我现在明白了一点。
Sandi Metz有一个很好的演讲,她在那里重构了一个非常多毛的if-statement,但是却没有多less意思: https : //www.youtube.com/watch?v = 8bZh5LMaSmE
我读过你链接的post,似乎他们大多是在谈论删除条件的需要在一个类 ,而不是与所有的代码一般混淆。 这个想法是,如果你需要检查一个对象的状态(使用一个条件)来确定它是否具有某些function,那么实际上你有两个对象(一个支持function,一个不支持),应该定义为两个相关的类。
我有一位同事告诉我,他曾经为一家公司做过工作,他们没有在代码中使用条件语句(“if”和“switch”语句),他们让代码中的所有决定都使用多态性和(我猜)一些其他的OO原则。
我认为你的同事误解了一些东西,或者用错误的词语来解释。 而且你不能完全避免条件陈述。
有一点要说的是:如果OOP里面的声明泛滥,可能是编程不好的一个症状。 一些例子:
不要使用如果检查函数的返回值就像一个旧的C风格的编程:
int ret = some_func(); if (ret != null) //do something
这是典型的C代码,但与OOP你应该使用exception:
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 }
有时候,如果说扩散与糟糕的devise有关。 在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语句的另一个例子,可能与糟糕的devise有关。 如果两个派生对象在基类BaseClass中定义了一个公共方法,那么可以调用该方法而不是检查它们的具体types并投射它们:
base.commonMethod();
有时候方法中的条件是不好的,因为它们表示你只是在一个方法中执行多个函数或多个types的方法。
如果您有一个名为汽车和汽车和自行车的子类,和一个方法,如:
drive(Automobile a) if (a.isCar) // do stuff else if (a.isBike) // do stuff
你最喜欢做错事。 即使它不是基于types的开关,通常也可能是错误的。 如果方法根据某个variables执行多个函数,则通常尝试执行多个操作,可能应该将其分为多个方法。
例如:
save(Car c) if (c is new) // do some stuff else if (c is old) // do some stuff
可能会被分解成保存和更新,因为它们是两个不同的function。 虽然这取决于。
完全禁止,如果陈述是愚蠢的,因为他们有许多有效的用例。
避免条件并不意味着你需要通过多态性或inheritance来完成它,例如:
你有3个不同的文件夹来存储上传的图像,上传的video和上传的PDF
您可以编写代码为:
uploadMedia(mediaType){ if(mediaType == images){ uploadTo("myProject/images"); }else if(mediaType == videos){ upoloadTo("myProject/videos); }else if(mediaType == pdf){ uploadTo("myProject/pdf"); } }
人们可能会使用的另一种select是开关柜:
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)); }
这是一种伪代码,所以可能会出现语法错误,但总的来说,这个概念也有助于避免条件。 也可以减less一行代码。