一. 为什么要消除 if-else
当写下第一行 if-else
时,就为发展成几十个 if-else
埋下了伏笔.
当一个 if-else 有可能臃肿时,那么它一定会臃肿. --墨菲
一个例子:
$userType = '';
if ($userTypeID == 1){
$userType = 'Admin';
}elseif($userTypeID == 2){
$userType = 'Corporate Customers';
}
看起来非常美妙,简洁.但是当系统慢慢复杂化,角色不断的丰富,就变成这样的代码:
$userType = '';
if ($userTypeID == 1){
$userType = 'Admin';
}elseif($userTypeID == 2){
$userType = 'Corporate Customers';
}elseif($userTypeID == 3){
$userType = 'Editorial Users';
}elseif($userTypeID == 4){
$userType = 'Photographers';
}elseif($userTypeID == 5){
$userType = 'Vendors';
}
来个极端的例子:
可以说非常可怕了.
二. 如何消除 if-else
消除这种条件里都是定值的 if-else
我们可以采用 查表法
来消除.
通过容器将对应的关系进行存储。通过运算得出相应关系中的其中一方的结果,再通过这个结果去容器中找对应的另一个内容
通俗的说,就是建立一个对象或者数组的 hash
表, key
值存储条件判断, value
存储符合该条件判断的逻辑处理.
比如上面的代码可以写成:
const USER_TYPE_ADMIN = 1;
const USER_TYPE_CORPORATE = 2;
const USER_TYPE_EDITORIAL = 3;
const USER_TYPE_PHOTOGRAPHERS = 4;
const USER_TYPE_VENDORS = 5;
public function getUserTypeName($key = null){
$data = array(
self::USER_TYPE_ADMIN => 'Admin',
self::USER_TYPE_CORPORATE => 'Corporate Customers',
self::USER_TYPE_EDITORIAL => 'Editorial Users',
self::USER_TYPE_PHOTOGRAPHERS => 'Photographers',
self::USER_TYPE_VENDORS => 'Vendors',
);
return $key === null ? $data : (isset($data[$key]) ? $data[$key] : '');
}
这样,上面的一大段的 if-else
就一行代码搞定: $userType = User::getUserTypeName($userTypeID)
用 JavaScrip 语言来描述:
let userTypeObj = {
1: 'Admin',
2: 'Corporate Customers',
3: 'Editorial Users',
4: 'Photographers',
5: 'Vendors',
};
let userTypeName = userTypeObj[userTypeID];
上面的例子只是不同的 userTypeID 获取不同的 userTypeName. 考虑更复杂的情况,当不同的 userTypeID 时进行不同逻辑处理.
if (userTypeID == 1) {
//Todo ...
} else if(userTypeID == 2) {
//Todo ...
} else if(userTypeID == 3) {
//Todo ...
} else if(userTypeID == 4) {
//Todo ...
}
这个时候可以把里面的逻辑处理代码抽出来为一个函数:
let userTypeObj = {
1: () => {
//Todo...
},
2: () => {
//Todo...
},
3: () => {
//Todo...
},
4: () => {
//Todo...
},
};
userTypeObj[userTypeID]();
以上代码也可以以 php
的可变变量/面向对象的多态特性来实现.
缺点:查表法的实现,要做越界检查,还要确保下标计算不会重复,如果使用面向对象的多态特性来实现,也有策略类增多等问题.
这个查表法的实现,其实是策略模式的思想.
策略模式指的是定义一系列的算法,把他们一个个的封装起来.策略模式的目的就是将算法的使用与算法的实现分离开来.
更多关于策略模式的讲解,请看这里
三. 总结
if-else 当然是有用的,比如 mysql 链接, curl 的返回码等等.当开始写的时候,只有一个 if-else ,我们可以不去消除,但是当要写到第三个第四个分支,或者每个条件分支里面都有大段大段的逻辑处理代码,我们就要考虑消除它了.
当条件语句不是定值,而是范围值的时候,如何消除 if-else
求教:
if(x < 30){
//todo
}else if(x >= 30 ){
//todo
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。