V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
MaZiT
V2EX  ›  程序员

关于代码中的 if else 重构

  •  
  •   MaZiT · 2018-03-19 09:15:34 +08:00 · 7048 次点击
    这是一个创建于 2471 天前的主题,其中的信息可能已经有所发展或是发生改变。

    写接口的时候,经常需要验证参数的数据类型、参数的值。还有一些选填 /必选之类的判断.

    如果是用普通的 if esle 去判断的话,导致代码不优雅,后期迭代困难. 在知乎上看的 “如何优雅地解决项目中可能存在的很多的 if/else ” 也不太理解设计模式, 大家平常是用什么方式可以解决呢或者是大家有什么建议应该看哪些书、方法之类的? 求指点迷津,谢谢

    45 条回复    2018-03-19 17:30:24 +08:00
    MaZiT
        1
    MaZiT  
    OP
       2018-03-19 09:20:29 +08:00
    使用的是 php 语言....目前用的是 tp5 框架
    torbrowserbridge
        2
    torbrowserbridge  
       2018-03-19 09:22:21 +08:00 via Android
    你需要的是 validation 组件
    powergx
        3
    powergx  
       2018-03-19 09:26:28 +08:00 via iPhone
    重构 重要的是程序的结构 /流程,这种 if else 可有可无,在项目中无伤大雅
    LevineChen
        4
    LevineChen  
       2018-03-19 09:29:44 +08:00   ❤️ 1
    $error = 'success';

    do{

    if(!$user){
    $error = 'need login';
    break;

    }

    if(!$a){
    $error = 'a not set' ;
    break;
    }

    $uid = $user->id;

    }while(false)
    graysheeep
        5
    graysheeep  
       2018-03-19 09:32:56 +08:00
    validation
    torbrowserbridge
        6
    torbrowserbridge  
       2018-03-19 09:33:11 +08:00
    @LevineChen 这啥玩意,简直看不懂。你是来黑 php 的?
    param
        7
    param  
       2018-03-19 09:35:22 +08:00
    assert?
    irenicus
        8
    irenicus  
       2018-03-19 09:35:40 +08:00 via Android
    复杂的 if else 可以重构为 dispatch table,相当于把逻辑抽象成数据另外保存,原本的逻辑本身就变成了遍历这个数据
    nickel123666
        9
    nickel123666  
       2018-03-19 09:38:21 +08:00
    5 楼+1,有个叫做 validation 的东西,可以参考一下。
    daydaydayup
        10
    daydaydayup  
       2018-03-19 09:41:28 +08:00
    我不知道是不是因为我的水平低的问题.用其他组件经常被别人鄙视.你们有没有这样的情况?
    xzpjerry731
        11
    xzpjerry731  
       2018-03-19 09:44:58 +08:00
    有些 if else 的作用可以用哈希表代替。
    zenxds
        12
    zenxds  
       2018-03-19 09:45:45 +08:00
    策略模式了解一下
    songz
        13
    songz  
       2018-03-19 09:46:56 +08:00
    switch case
    yangfch3
        14
    yangfch3  
       2018-03-19 09:47:47 +08:00
    策略模式了解一下
    MaZiT
        15
    MaZiT  
    OP
       2018-03-19 09:49:38 +08:00
    @yangfch3 谢谢
    wwdyy
        16
    wwdyy  
       2018-03-19 09:49:46 +08:00
    看一遍
    JavaScript 设计模式与开发实践

    看一遍自己的代码



    然后-----
    看一遍
    JavaScript 设计模式与开发实践

    看一遍自己的代码

    MaZiT
        17
    MaZiT  
    OP
       2018-03-19 09:50:00 +08:00
    @powergx 但是这样会导致后面的迭代更多 if else 吧...
    laobaozi
        18
    laobaozi  
       2018-03-19 09:50:11 +08:00
    尽早返回
    suikator
        19
    suikator  
       2018-03-19 09:50:41 +08:00 via Android
    @torbrowserbridge #6 do{...}while(false) 简化嵌套 if
    MaZiT
        20
    MaZiT  
    OP
       2018-03-19 09:50:57 +08:00
    @xzpjerry731 方便给个 demo 吗?我不太理解
    zjp
        21
    zjp  
       2018-03-19 09:52:56 +08:00 via Android
    不能避免多层 if 的话,及早处理错误情况然后返回
    https://coolshell.cn/articles/17757.html
    yangfch3
        22
    yangfch3  
       2018-03-19 10:02:02 +08:00
    @MaZiT
    @xzpjerry731 的意思应该就是使用策略模式,因为策略模式就是用一个哈希表来存储不同的策略,然后策略管理器根据不同的策略 key 来调用不同的策略属性。

    下面是一个简单的策略模式用例:
    ```
    function logicCall(type, ...args) {
    // 其他逻辑

    registeredTypeHandler[type] && registeredTypeHandler[type](...args); // 这部分还可以新增一个策略控制器进行管理
    }

    // 策略哈希表
    var registeredTypeHandler = {
    foo: _foo,
    bar: _bar
    };

    function _foo(...args) {
    ...
    }

    function _bar(..args) {
    ...
    }
    ```
    lurenw
        23
    lurenw  
       2018-03-19 10:09:40 +08:00
    状态机了解一下
    Todd_Leo
        24
    Todd_Leo  
       2018-03-19 10:13:01 +08:00
    Pattern Matching 了解一下:

    ```
    x match {
    case 1 => "one"
    case 2 => "two"
    case _ => "many" // case _ will trigger if all other cases fail.
    }
    ```
    daisyxdx
        26
    daisyxdx  
       2018-03-19 10:32:29 +08:00
    弱弱地提一下 职责链模式。。。不知道有没有啥问题
    LevineChen
        27
    LevineChen  
       2018-03-19 10:39:01 +08:00
    @torbrowserbridge 老铁我只能说你理解能力比较差.
    CFMY
        28
    CFMY  
       2018-03-19 10:40:31 +08:00
    策略模式不能避免 if else,如果你真的需要很多判断,无论用什么模式都无法避免这些判断
    只是说策略模式更符合开放封闭原则,但是代价是你需要更多地代码去写接口以及更多类
    与其套用模式,不如重新审视你的流程是否可以分解,从而让代码更清晰
    Building
        29
    Building  
       2018-03-19 10:57:58 +08:00 via iPhone
    只是为了看起来更优雅给自己找麻烦完全没必要,把一堆判断分散到各个角落,一段时间看回来肯定会骂自己傻逼。老老实实写就好。
    crysislinux
        30
    crysislinux  
       2018-03-19 11:03:18 +08:00
    逻辑上相关的 if else 我现在倾向于拆分成多个 function,逻辑不相关的参数类型检查,就用类似 table 的东西。以前就爱搞些多态。。结果多写了 n 多代码。

    没必要还是不要搞复杂了。
    gnaggnoyil
        31
    gnaggnoyil  
       2018-03-19 11:03:19 +08:00
    LZ 我告诉你一个笨但是有用的办法:画真值表硬怼 :)
    realityone
        32
    realityone  
       2018-03-19 11:06:57 +08:00 via iPhone
    不要写 else
    qiyon
        33
    qiyon  
       2018-03-19 11:11:32 +08:00
    参数校验可以看下
    Yii 的 Form Model
    Laravel 的 Validation
    之类的实现

    可以实现参数的默认值、过滤、以及校验
    qiyon
        34
    qiyon  
       2018-03-19 11:15:34 +08:00
    还有 symfony 的 entity,TP 也有 Model 的 validate
    nicevar
        35
    nicevar  
       2018-03-19 11:27:15 +08:00
    公司代码服务器配个 SonarQube, 这种 if else 多几层就过不去,一段时间就治好了你的症状
    torbrowserbridge
        36
    torbrowserbridge  
       2018-03-19 11:29:38 +08:00 via Android
    @LevineChen 老铁我说的是,你代码有问题。set 判断都是错的
    windygoose
        37
    windygoose  
       2018-03-19 11:39:09 +08:00
    四楼的写法一般常见在 C 中,关注点是 do while 和 break 的使用
    TaoSama
        38
    TaoSama  
       2018-03-19 13:58:43 +08:00 via Android
    这种东西有两种解决方案
    一个是尽量用函数式的方法
    另一个就是把脏东西藏起来 用可靠的 validation 的库 或者自己写相关的库 把 if..else 藏起来
    koalli
        39
    koalli  
       2018-03-19 14:02:18 +08:00
    @windygoose 我也觉得是 C/C++转 php 的老司机,这个写法很常见,包括一些宏为了避免展开出问题也会用这样的写法
    AwayEM
        40
    AwayEM  
       2018-03-19 14:07:34 +08:00
    form validator 很多的把 vue react 自带的好多啊, 后台框架的 form 类也有好多抽离验证的,我用的 spring flask django 以及前端的 vue 都有。
    newmlp
        41
    newmlp  
       2018-03-19 14:38:16 +08:00
    if 不就是判断用的么,有什么不优雅的,不要为了设计而设计,而且如果判断数量不多的话,改用其他会带来性能问题,虽然不多
    r7st
        42
    r7st  
       2018-03-19 14:41:30 +08:00
    @torbrowserbridge do while 这不是??
    zjsxwc
        43
    zjsxwc  
       2018-03-19 14:45:19 +08:00
    责任链模式吧,专门用来避免超多 if-else 的情况
    cljnnn
        44
    cljnnn  
       2018-03-19 14:49:00 +08:00 via Android
    《代码大全》里面对多层 if else 的建议是,if 里面总是处理预期情况,else 处理其他情况。 看起来不太优雅,但是逻辑很清楚(这一句我说的)。
    yidinghe
        45
    yidinghe  
       2018-03-19 17:30:24 +08:00
    不要一开始就通过设计去避免 if-else,等将来分支确实多起来了再考虑也不迟。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1133 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 18:45 · PVG 02:45 · LAX 10:45 · JFK 13:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.