作者热门文章
- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有很多 IF 语句,每个语句都启动一个函数。
有没有明显的方法可以使这段代码更简单?
每个 IF 启动不同的功能,但它仍然看起来有点矫枉过正。
if ($this->machine == '' AND $this->date_from == '' AND $this->date_to == '' AND $this->date_like == '' AND $this->article_or_tool == '') {
$this->AllTime();
}
if ($this->machine <> 0 AND $this->date_from == '' AND $this->date_to == '' AND $this->date_like == '' AND $this->article_or_tool == '') {
$this->ByMachine();
}
if ($this->machine == '' AND $this->date_from <> 0 AND $this->date_to <> 0 AND $this->date_like == '' AND $this->article_or_tool == '') {
$this->ByDate();
}
if ($this->machine <> 0 AND $this->date_from <> 0 AND $this->date_to <> 0 AND $this->date_like == '' AND $this->article_or_tool == '') {
$this->ByMachineByDate();
}
if ($this->machine == '' AND $this->date_from == '' AND $this->date_to == '' AND $this->date_like <> 0 AND $this->article_or_tool == '') {
$this->ByDateLike();
}
if ($this->machine <> 0 AND $this->date_from == '' AND $this->date_to == '' AND $this->date_like <> 0 AND $this->article_or_tool == '') {
$this->ByMachineByDateLike();
}
if ($this->machine == '' AND $this->date_from == '' AND $this->date_to == '' AND $this->date_like == '' AND $this->article_or_tool <> 0) {
$this->ByArticle();
}
if ($this->machine <> 0 AND $this->date_from == '' AND $this->date_to == '' AND $this->date_like == '' AND $this->article_or_tool <> 0) {
$this->ByMachineByArticle();
}
if ($this->machine == '' AND $this->date_from <> 0 AND $this->date_to <> 0 AND $this->date_like == '' AND $this->article_or_tool <> 0) {
$this->ByDateByArticle();
}
if ($this->machine == '' AND $this->date_from == '' AND $this->date_to == '' AND $this->date_like <> 0 AND $this->article_or_tool <> 0) {
$this->ByDateLikeByArticle();
}
if ($this->machine <> 0 AND $this->date_from <> 0 AND $this->date_to <> 0 AND $this->date_like == '' AND $this->article_or_tool <> 0) {
$this->ByMachineByDateByArticle();
}
if ($this->machine <> 0 AND $this->date_from == '' AND $this->date_to == '' AND $this->date_like <> 0 AND $this->article_or_tool <> 0) {
$this->ByMachineByDateLikeByArticle();
}
解决方案
这是我重构后的代码:
function MethodPicker() {
$machine = $this->machine <> 0;
$date_from = $this->date_from <> 0;
$date_to = $this->date_to <> 0;
$date_like = $this->date_like <> 0;
$article_or_tool = $this->article_or_tool <> 0;
$decision = array($machine, $date_from, $date_to, $date_like, $article_or_tool);
$decisions = array(
'AllTime' => array(false, false, false, false, false ),
'ByMachine' => array(true, false, false, false, false ),
'ByDate' => array(false, true, true, false, false ),
'ByMachineByDate' => array(true, true, true, false, false ),
'ByDateLike' => array(false, false, false, true, false ),
'ByMachineByDateLike' => array(true, false, false, true, false ),
'ByArticle' => array(false, false, false, false, true ),
'ByMachineByArticle' => array(true, false, false, false, true ),
'ByDateByArticle' => array(false, true, true, false, true ),
'ByDateLikeByArticle' => array(false, false, false, true, true ),
'ByMachineByDateByArticle' => array(true, true, true, false, true ),
'ByMachineByDateLikeByArticle' => array(true, false, false, true, true ),
);
$method = array_keys($decisions, $decision, true);
$method && list($method) = $method;
$method && $this->$method();
}
最佳答案
首先我会做一些标准的重构。不知道我为什么那样做,但这是什么:
用局部变量替换属性,比如
$machine = $this->machine;
同样适用于这些条件,但是仔细观察这些条件会发现每个变量只有两个状态,所以这实际上是每个变量只有一个条件(请参阅 Type Juggling ),这导致 真
或假
。分配条件,而不是:
$machine = $this->machine == '' || $this->machine == 0;
(感谢 martinstoeckli 正确的条件)
这将是一个开始。到现在为止的 if 子句已经改变并且会更紧凑。然而,为什么要停在这里呢?有一个当前的决定:
$decision = [$machine, $date_from, $date_to, $date_like, $article_or_tool];
并且有一组决策可供选择:
$decisions = [
'AllTime' => [true, true, true, true, true],
...
];
所以需要做的就是找到决策并执行方法:
$method = array_keys($decisions, $decision, true);
$method && $this->$method();
if block 已变成矩阵。该功能已映射到它的一个状态。
您丢失了字段上的名称,但是,您可以通过注释解决该问题:
$decisions = [
// machine from to like article
'AllTime' => [true , true, true, true, true],
...
];
一目了然:
$machine = $this->machine == '' || $this->machine == 0;
... # 4 more times
$decision = [$machine, $date_from, $date_to, $date_like, $article_or_tool];
$decisions = [
'AllTime' => [true, true, true, true, true],
... # 11 more times
];
$method = array_keys($decisions, $decision, true);
$method && $this->$method();
如果 this 所在的类表示一个值对象,我建议您将决策移到它自己的类型中,然后将该决策类型用作单个方法对象。将使您以后能够更轻松地做出不同的决策集。
关于php - 如何减少 IF 语句的数量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13138952/
我是一名优秀的程序员,十分优秀!