今天接手了前同事的一個項目肴甸。一個簡單的應(yīng)用箕昭,竟然寫了2100多行代碼凤瘦,40個action方法哑蔫,最長的一個action有130多行。
這圖的底部曲線直接就反應(yīng)了我看到這些代碼的心情乍迄,波濤洶涌管引,又如滔滔江水,連綿不絕闯两。
如果可以褥伴,我不想接手這樣的爛代碼。它具備了以下特征:
- 函數(shù)過長
- if else 多層嵌套
- 大量重復(fù)性代碼
- 命名不規(guī)范漾狼、混亂
- 大量無用代碼(接口不用了重慢,代碼不刪)
- 無用注釋
代碼片段示例
public function actionKidinfo() {
$userInfo = $this->userinfo; //獲取身份
$status = array();
$resourceId = $this->request->get('resource_id'); //書本資源ID
if (is_object($userInfo) && $userInfo->userId !== NULL) {
$returnUser['profile']['type'] = $userInfo->role;
$returnUser['profile']['_id'] = $userInfo->userId;
$returnUser['profile']['display_name'] = $userInfo->name;
$childrenInfo = isset($this->user['children']) ? $this->user['children'] : [];
$data = [];
foreach ($childrenInfo as $key => $value) {
$childData = SsoHelper::getUserInfoByIds($value);
if ($childData['ret'] == 0 && isset($childData['data'][$value])) {
$returnUser['profile'][$key] = $childData;
$result['profile']['children'][$key]['kid_id'] = $value;
$result['profile']['children'][$key]['name'] = $returnUser['profile'][$key]['data'][$value]['display_name'];
$result['profile']['children'][$key]['thumb'] = $returnUser['profile'][$key]['data'][$value]['avatar'];
$result['profile']['children'][$key]['status'] = $this->recommend->Kidresourceid($value, $resourceId);
if ($result['profile']['children'][$key]['status'] == 'true') {
$status[$key] = '1';
}
}
}
if (array_sum($status) == count($childrenInfo)) {
$status = 1;
} else {
$status = 0;
} // 給到是否可以發(fā)送推薦 關(guān)鍵字
if (!empty($result['profile']['children'])) {
$return = ['kidsinfo' => $result['profile']['children'], 'status' => $status];
return $this->returnData(OKCODE::ok, '', $return);
} else {
return $this->returnData(OKCODE::no_records_found, '沒有相關(guān)的信息', ['kidsinfo' => [], 'status' => $status]);
}
} else {
return $this->returnData(OKCODE::no_records_found, '沒有相關(guān)的信息', ['kidsinfo' => [], 'status' => $status]);
}
}
為了不讓自己踩坑,我花了約20分鐘(主要時間花在理解代碼上)進行重構(gòu)逊躁,并調(diào)試完畢的最后代碼如下:
public function actionKidinfo() {
$userInfo = new UserInfo;
if (!is_object($userInfo) || $userInfo->userId === NULL) {
return $this->returnData(OKCODE::no_records_found, '沒有相關(guān)的信息',
['kidsinfo' => [], 'status' => 0]);
}
$resourceId = Yii::$app->request->get('resource_id');
$children = UserHelper::getChildrenBy($userInfo->userId);
$isAllChildrenRecommend = 1;
foreach ($children as $key => $child) {
$recommendStatus = RecommendModel::isResourceRecommendToKid($child['id'], $resourceId);
$children[$key]['status'] = $recommendStatus;
if (!$recommendStatus) {
$isAllChildrenRecommend = 0;
}
}
return $this->returnData(OKCODE::ok, '',
['kidsinfo' => $children, 'status' => $isAllChildrenRecommend]);
}
下面來說下我對付爛代碼的一點心得似踱。
1、刪稽煤,快刀斬亂麻
在前端同事的配合下核芽,我首先找出了那些已經(jīng)廢棄了的接口,40個接口酵熙,有用的竟然只有10個轧简。一頓刪除后,整個類只剩下800多行代碼了绿店。刪完后瞬間心情好轉(zhuǎn)吉懊。
而在【代碼片段示例】途中中庐橙,也存在了無用的代碼假勿。
$returnUser['profile']['type'] = $userInfo->role;
$returnUser['profile']['_id'] = $userInfo->userId;
$returnUser['profile']['display_name'] = $userInfo->name;
這段代碼就是各位新手都十分喜歡的操作(復(fù)制粘貼)而留下的代碼隱患,在整個代碼中态鳖,變量:type转培、_id、display_name壓根是沒有用到過的浆竭。
程序員信條:復(fù)制粘貼一時爽浸须,一直復(fù)一直爽惨寿!
對于沒有用的代碼千萬不要留,果斷點刪删窒。
2裂垦、減少if else 嵌套,盡早返回
$userInfo = $this->userinfo; //獲取身份
$status = array();
$resourceId = $this->request->get('resource_id'); //書本資源ID
if (is_object($userInfo) && $userInfo->userId !== NULL) {
} else{
return $this->returnData(OKCODE::no_records_found, '沒有相關(guān)的信息', ['kidsinfo' => [], 'status' => 0]);
}
改為
$userInfo = new UserInfo;
if (!is_object($userInfo) || $userInfo->userId === NULL) {
return $this->returnData(OKCODE::no_records_found, '沒有相關(guān)的信息',
['kidsinfo' => [], 'status' => 0]);
}
3肌索、提煉專職的函數(shù)
在【代碼片段示例】中蕉拢,有獲取孩子列表的功能,而這個功能在其他地方也用到诚亚。為了更好地復(fù)用晕换,我提煉了一個getChildrenBy($userId)的函數(shù)
public static function getChildrenBy($userId) {
$response = SsoHelper::getUserInfoByIds($userId);
if (isset($response['ret']) && $response['ret'] == 0
&& isset($response['data'][$userId])) {
$userData = $response['data'][$userId];
} else {
$userData = [];
}
$children = isset($userData['children']) ? $userData['children'] : [];
$childrenData = SsoHelper::getUserInfoByIds($children);
if ($childrenData['ret'] == 0) {
$result = [];
foreach ($childrenData['data'] as $childId => $childData) {
$result[] = [
'id' => $childId,
'name' => $childData['display_name'],
'avatar' => $childData['avatar'],
'kid_id' => $childId,
'thumb' => $childData['avatar'],
];
}
return $result;
} else {
return [];
}
}
4、根據(jù)情景對進行有意義的命名
在【代碼片段示例】中
$result['profile']['children'][$key]['status'] = $this->recommend->Kidresourceid($value, $resourceId);
這個Kidresourceid()是什么站宗?第一眼看去闸准,就要奔潰了。通讀下來梢灭,我才知道原來是這個資源是否推薦給了孩子夷家。那么按照最簡單的說法,我改成了
$result['profile']['children'][$key]['status']
= $this->recommend->isResourceRecommendToKid($value, $resourceId);
還有其他的變量有混淆敏释,我就不再列舉了瘾英。
5、刪掉無用注釋
$userInfo = $this->userinfo; //獲取身份
$resourceId = $this->request->get('resource_id'); //書本資源ID
if (array_sum($status) == count($childrenInfo)) {
$status = 1;
} else {
$status = 0;
} // 給到是否可以發(fā)送推薦 關(guān)鍵字
雖然大家都推薦多寫注釋颂暇,但是這些無用的注釋就不用寫了缺谴,寫了還給我造成混亂 “// 給到是否可以發(fā)送推薦 關(guān)鍵字” 通讀下來這個壓根就不是這個意思,如果是在需求緊急的情況下耳鸯,這簡直令人發(fā)狂湿蛔。
在一天內(nèi)不斷重復(fù)這幾個步驟后,代碼整體的縮略圖如下:
看到這張圖县爬,心情總算平靜了許多阳啥。
其實重構(gòu)完后,整個人特別累财喳。這次里面還是相當感謝前端同事的配合察迟,沒有配合,很難實現(xiàn)重構(gòu)耳高,因為那30個接口就會花費更多的時間扎瓶。而且這次重構(gòu)的是不涉及到其他關(guān)聯(lián)應(yīng)用的模塊,否則花費的時間將更加多泌枪。