我有很多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块已变为矩阵.该函数已映射到它的一个状态.
你松开了字段上的名字,但是,你可以通过评论解决这个问题:
$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();
如果它所在的类表示一个值对象,我建议您将决策移动到它自己的类型中,然后将该决策类型用作单个方法对象.将使您以后能够更轻松地做出不同的决策.