如果我有一个从几个地方调用的函数,并且它需要满足某些条件才能执行它的任何条件,应该在哪里检查该条件?在我的例子中,它是用于绘图 - 如果按住鼠标按钮,则执行绘图逻辑(这是在拖动时在鼠标移动处理程序中完成的。)
选项1表示将其放入函数中以确保其得到检查。抽象,如果你愿意的话。
public function Foo() {
DoThing();
}
private function DoThing() {
if (!condition) return;
// do stuff
}
我遇到的问题是,在阅读可能远离Foo
的{{1}}代码时,它看起来像一个错误。第一个想法是没有检查条件。
然后,选项二是在致电之前检查。
DoThing
这样做效果更好,但现在你必须担心从你称之为的任何地方进行检查。
选项三是将函数重命名为更具描述性。
public function Foo() {
if (condition) DoThing();
}
这是“正确”的解决方案吗?或者这有点太过分了?我觉得如果一切都像这个函数名称将开始复制他们的代码。
关于这是主观的:当然是,并且可能没有正确的答案,但我认为它仍然完美在家。从比我更好的程序员那里获得建议是第二种最好的学习方式。主观问题正是谷歌无法回答的问题。
答案 0 :(得分:5)
根据DRY,我会选择第一个。
public function Foo() {
DoThing();
}
private function DoThing() {
if (!condition) return;
// do stuff
}
一旦习惯了模式,在代码中看到一个DoThing()
就不那么令人不安了。您将开始像EnsureThingDone()
一样阅读。
答案 1 :(得分:2)
选项四,将谓词和实际调用包装在第三个函数中。
function DoThing() {
// do stuff
}
function DoThingOnlyIfCondition() {
if (!condition) return;
DoThing();
}
function Foo() {
DoThingOnlyIfCondition();
}
// Foo version 2
function FooBar() {
DoThing();
}
现在,Foo或任何函数都可以使用最合适的DoXXX()版本。
答案 2 :(得分:0)
我喜欢检查函数内的前提条件,
public function DoThing()
{
ValidatePreconditions();
DoWork();
}
private function DoWork()
{
//Do the actual work;
}
这样我确定在执行我的函数之前满足所有正确的前置条件,并且每次调用函数时都不需要消费者添加不必要的代码。
答案 3 :(得分:0)
您可以使用类型系统。将参数设置为DoThing只有在传递前置条件时才能实例化的对象。
这样做的一个简洁方法是将DoThing作为该对象的实例方法。