背景
最近公司物流部那邊經常叫我更改我維護的一個erp系統修改訂單狀態部分,發現以前開發寫的太亂了,所以來重構一下。
業務分解
- 公司分為客服、採購、物流、財務等各個部門,需要根據業務需求對erp系統上訂單狀態進行修改;
- 目前訂單狀態有已下單、有效單、已採購、已入庫、重出單、已出倉、、已發貨、問題件、拒籤、已簽收、退貨、退件單、已收款、確認中、風險單、已缺貨、取消單、攔截單等,不同的訂單狀態修改可能會涉及到其他業務,而且因為單量較大,所以各部門都是匯入批次修改的。
程式碼分析
目前程式碼是寫在一個function,不同的訂單狀態透過前端傳過來的code欄位進行修改:
每一個狀態的程式碼可能相同,有些也有差異,以下舉幾個例子:
-
大部分預設的邏輯是透過訂單號或快遞單號判斷訂單是否存在,然後判斷訂單狀態是否允許被修改為指定的狀態:
-
有些狀態的修改不同的角色允許操作的訂單範圍不同:
-
更改為發貨狀態需要調私有function修改庫存:
-
看完以上程式碼目測對程式碼敏感或有程式碼潔癖的人可能會有各種吐槽,下面我們一步步來重構這份程式碼。
重構思路和實現
- 程式碼中存在大量
\App\Model\Simple\Order::
的語句,類使用use App\Model\Simple\Order as OrderModel
匯入一次,後文可以直接用OrderModel
。注:這個Controller的類名就叫order,所以要給order Model 起別名。
OrderModel::select(DB::raw('id,type_id'))
改為OrderModel::select('id','type_id')
(ps:目測以前的開發不想寫這麼多單引號吧)-
$_order_type = \App\Model\Simple\OrderType::all(); foreach ($_order_type as $value) { $types[$value->code] = array( 'id' => $value->id ); } 改為: $_order_type = OrderType::select('id', 'code')->pluck('id', 'code'); 之後: $types['fahuo']['id']之類的獲取訂單狀態的id改為: $_order_type['fahuo']
- 大部分預設的邏輯都需要判斷訂單狀態是否允許被修改為指定的狀態,可以寫個對映陣列在model裡,然後寫個當前order_type 是否可被修改為指定type的function,具體邏輯如下:
在orderTypeModel加:
(ps:吐槽訂單狀態命名的希望可以給個好的解決方案)
加入檢驗的function:
/**
* 檢驗訂單狀態是否可改
* @param $check_type 當前要修改的狀態
* @param $check_content_type 允許被改的狀態
* @return bool
*/
public static function checkTypeAuth($check_type,$check_content_type){
if(empty(self::$typeMap[$check_type])||in_array($check_content_type,self::$typeMap[$k_type])){
return true;
}
return false;
}
# 因為後面有迴圈查訂單狀態表,這個表的內容基本不改,所以在orderTypeModel加:
/**
* 從快取中獲取資料
* @return mixed
*/
public static function getFromCached()
{
return Cache::remember('order_type_all', 5*60, function(){
return self::all();
});
}
加入以上程式碼後所有的code片段都可以做以下改動:
- 做了以上改動後可以提取出所以相同的邏輯,寫在一個code片段裡面,對比資料如下圖:
- 此外有些程式碼太多if_else,可以做如下修改:
修改前:
修改後:
注: 以上程式碼(修改前、修改後)都放在github上。點選連結
小結
透過此次程式碼的重構,總結以下成果:
- 程式碼比之前更加簡潔,可讀性提高;
- 透過map對映來管理可修改狀態,不用每次都在code程式碼段裡找,管理程式碼更方便;
- 以後有新的訂單狀態要修改,新增程式碼可以找對應相似code片段,如果存在可以不用複製一段長長的code,節約程式碼量。
引出問題
自己在改完這份程式碼之後感覺還是不滿意,因為還是有些地方可以改進的:比如圖八可以看出還是有很多相似都程式碼但無法獨立開來;訂單狀態的命名;還有一些我沒發現的問題。
原始碼連結前面已經給出了,希望有能人異士幫忙指點一下哈!
本作品採用《CC 協議》,轉載必須註明作者和本文連結