如何将布尔参数传递给函数以充当开关



如果标题不清楚,我很抱歉,但我觉得这很难描述。基本上,我有一个函数,它在给定班级ID号和日期的情况下查找班级(学校类型)的实例。如果需要,函数还可以创建一个新的类实例。

function get_class_instance($class_id, $date, $create)

函数内部是class_instances表上的数据库选择,使用class_iddate作为参数。如果找到匹配的class_instance,则返回其ID。如果没有找到,则存在create参数的条件。如果为true,则使用数据库插入创建一个新的class_instance,并返回其ID。如果为false,则数据库中不会发生任何更改,并返回false

我仍然是PHP和编码的初学者,所以我认为可能有更好的方法。问题是,在调用函数时,有些人可能不清楚为什么要传递布尔值。

$original_cinstance_id = get_class_instance($original_class_id, $original_date, 1);

在Robert Martin的《清洁代码》一书中,将布尔标志传递给函数,使它们做两件不同的事情,而不是只做一件,这被认为是一种代码气味。建议的更好的选择是具有两个函数get_whatevercreate_whatever

虽然代码气味取决于上下文,但我认为布尔标志气味在这种情况下确实适用,因为创建东西不同于仅仅读取它。前者是命令,后者是查询。所以他们应该分开。一个改变状态,另一个不改变。拆分它们有助于更好的语义和关注点的分离。此外,它将把函数的循环复杂度降低一个分支,所以你将需要少一个单元测试来覆盖它

报价https://martinfowler.com/bliki/FlagArgument.html

布尔参数大声声明函数做的不止一件事。它们令人困惑,应该予以消除。

报价http://www.informit.com/articles/article.aspx?p=1392524

我的理由是,当我打电话时,单独的方法可以更清楚地传达我的意图。当我看到book(martin, false)时,不必记住标志变量的含义,我可以很容易地读取regularBook(martin)

其他讨论和阅读材料:

  • https://softwareengineering.stackexchange.com/questions/147977/is-it-wrong-to-use-a-boolean-parameter-to-determine-behavior
  • https://medium.com/@amlcurran/clean-code-the-curse-of-a-boolean参数-c237a830b7a3
  • https://8thlight.com/blog/dariusz-pasciak/2015/05/28/alternatives-to-boolean-parameters.html

您可以使用默认值来创建,因此如果您向它传递任何内容,它将充当数据库的正常"获取"操作。像这样:

function get_class_instance($class_id, $date, $create = false);

你可以这样查询你的ID:

$class_id = get_class_instance(1, "18-10-2017");

然后,无论何时需要在数据库上创建它,都可以将"true"传递给它:

$class_id = get_class_instance(1, "18-10-2017", true);

您可以传递一个真正的布尔值,而不是传递一个数字值,如下所示:

$original_cinstance_id = get_class_instance($original_class_id, $original_date, true);

此外,在函数的声明中,您可以指定一个默认值来避免每次传递布尔值:

function get_class_instance($class_id, $date, $create = false)

一个选项是创建一个枚举器,如下所示:

abstract class create_options {
const no_action = 0;
const create = 1;
}

所以现在你的函数调用看起来是这样的:

$original_cinstance_id = get_class_instance($original_class_id, $original_date, create_options::no_action);

在实践中,只要你的代码得到了很好的注释,那么这就不是布尔标志的主要问题,但如果你有十几个不同结果的可能选项,那么这可能会很有用。

正如其他人所提到的,在许多语言中,您也可以将参数设置为可选参数,并具有默认行为,除非调用者专门定义了该参数。

最新更新