React開發(fā)-使用抽象+工廠實現狀態(tài)機

日常開發(fā)遇到的一些問題?

  • 大量的if else
  • 大量的switch case
  • 代碼閱讀性差,擴展性差
  • 代碼耦合性強,復用率低

痛點

  • 以電商平臺訂單狀態(tài)的流轉為例


    image

    從圖中可以看到不同的訂單狀態(tài)對應不同的操作按鈕,在代碼中實現(偽代碼)

if (status === '待付款'){
    btns = ['取消訂單','去付款'];
}else if (status === '待發(fā)貨'){
    ...
}

或者使用switch case

switch (status){
    case '待付款':
        btns = ['取消訂單','去付款'];
        break;
    .
    .
    .
}

從上述代碼中可以看到,訂單狀態(tài)的一些判斷與業(yè)務代碼摻雜在一塊,不利于我們做擴展和復用

思考&實現

  • 使用對象來管理不同狀態(tài)下的UI展示效果
  • 比如:在是否需要展示操作按鈕的時候
status.canCancel() ? <button  /> ... // 是否需要取消訂單的按鈕
status.canGoPay() ? <button /> ...  // 是否需要去付款的按鈕
  • 從上述代碼中可以看到,status是代表了不同訂單狀態(tài)的一個對象,我們應該根據后端返回的狀態(tài)字段創(chuàng)建不同的status對象
// 根據狀態(tài)創(chuàng)建不同的狀態(tài)類(偽代碼)
createStatusObjWith (status) {
    let obj = undifined
    switch (status) {
        case '待付款':
            obj = new StatusWaitToPay()
            break;
        case '待發(fā)貨':
            obj = new StatusWaitToShip()
            break;
            ...
    }
    return obj
}

// 在狀態(tài)類中設置UI的一些操作
class StatusWaitToPay {
    canCancel () {
        return true
    }
    canGoPay () {
        return true
    }
}
  • 接下來完善一下代碼
// 抽象類,用來規(guī)定訂單狀態(tài)需要實現的方法
export default class OrderAbstractStatus {
    constructor(type) {
        this.type = type
    }
    // 是否支持取消訂單操作
    canCancel () {
        throw new Error("抽象方法,請不要直接調用")
    }
    // 是否支持去付款的操作
    canGoPay () {
        throw new Error("抽象方法,請不要直接調用")
    }
}
// 待付款狀態(tài)類
export default class StatusWaitToPay {
    constructor() {
       super(1) // 假設待付款訂單的status值為 1
    }
    canCancel () {
        return true
    }
    canGoPay () {
        return true
    }
}

// 使用工廠類 完成狀態(tài)類的創(chuàng)建操作
export default class OrderStatusFactory {
    createStatusObjWith (status) {
        let obj = undifined
        switch (status) {
            case '待付款':
                obj = new StatusWaitToPay()
                break;
            case '待發(fā)貨':
                obj = new StatusWaitToShip()
                break;
            ...
    }
    return obj
}
  • 接下來看如何使用
// 網絡請求成功后數據的處理
dealRemoteData (data) {
    let orderStatusFactory = new OrderStatusFactory()
    let status = orderStatusFactory.createStatusObjWith(data.status)
    this.setState({ status: status })
    ...
}

以上是解決問題的一種思路,歡迎大家的建議&討論

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容