首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
V2EX  ›  问与答

探讨三种方式哪种效率高、可读性、可维护性好: if-else、switch、和另外一种

  •  
  •   stevenkang · 37 天前 · 1359 次点击
    这是一个创建于 37 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我们现在有一个参数 type,需要根据 type 进行相应的代码处理( type 大概有 20+ 种情况),用题目中的三种方式如下

    if-else 方式

    if (type == 'type1') {
        // todo something
    } else if (type == 'type2') {
        // todo something
    }
    ...
    else if (type == 'typeN') {
        // todo something
    } else {
        // otherwise
    }
    

    switch 方式

    swtich(type) {
        case 'type1': /* todo something */ break;
        case 'type2': /* todo something */ break;
        ...
        case 'typeN': /* todo something */ break;
        default: /* otherwise */ break;
    }
    

    另外一种(我不知道这叫什么方式)

    static {
        // 这里的 put 可以通过别的方式装载,可以一次性写好了之后,需要扩展时主动添加到 map 里面(也可以用注解注入等方式)
        map.put('type1', new Type1Process())
        map.put('type2', new Type2Process())
        ...
        map.put('typeN', new TypeNProcess())
        map.put('default', new DefaultProcess())
    }
    proc = map.containsKey(type) ? map.get(type) : map.get('default')
    proc.exec()
    

    从执行效率、可读性、可维护性等多个方面来看,哪种方式综合评分更高?

    24 回复  |  直到 2019-08-16 10:12:19 +08:00
        1
    z42514   37 天前
    我选三
        2
    TomVista   37 天前
    20 种 type 可以排除 if else 了吧
        3
    mara1   37 天前
    放到字典里,差不多就是 3
        4
    hmellochan   37 天前
    那么多类型,明显三好。
        5
    Vegetable   37 天前
    2 和 3 在底层差不多是一样的吧,条件这么多我选 3.
        6
    672795574   37 天前   ♥ 1
    1,2 我选 1,踩过忘记加 break 的坑(自己的问题)
    3 应该是抽象过了,看着也有点符合开闭原则
    因此理论上新加一个 type 和 Processor 不需要测试原来的逻辑。
        7
    fuxiao11   37 天前 via Android
    3 其实是责任链模式的一种变形实现
        8
    kkkkkrua   37 天前
    spring 直接 getBean("xxx_TYPE1").exec()不更好么,
    其他方式直接 new 对应的实例,不用 if..
        9
    Justin13   37 天前 via Android
    当然是第三种字典啦。
        10
    tomoya92   37 天前 via iPhone
    性能上哪个最高呢
        11
    sun2920989   37 天前
    没看出来是什么语言,但是确定第三种方法是在 get 时才去实例化的吗?看着写法有点担心 put 时直接 new 了.
        12
    autoxbc   37 天前
    2 好,switch 故意不写 break 也是一种写法

    语句由上而下叠加执行,在需要共享一部分处理逻辑时有奇效。当然要防止别人打你
        13
    ianva   37 天前
    表驱动
        14
    jadec0der   36 天前
    第三种在代码大全 18 章叫「 表驱动法」
        15
    Leammin   36 天前 via Android
    少的时候 2,多的时候 3
        16
    murmur   36 天前
    我投 gotoy 一票
        17
    ywcjxf1515   36 天前 via iPad
    谷歌搜 if 策略模式 map v2ex,或者搜 if 状态模式 map v2ex。
        18
    zw1one   36 天前 via Android
    如果你 if 里的条件全长这个样子,那肯定 3 好。如果 if 条件会突然多两个奇怪的判断,用 3 就不好改。
        19
    pastgift   36 天前
    2 到 5 个分支用,每个分支代码量中等( 20 行以内) if-else
    3 到 10 个分支,每个分支代码量很少( 10 行以内) switch-case
    2 个分支以上,每个分支代码量很多,表驱动方式

    具体操作按个人喜好,项目要求,统一性洁癖,美观等因素调整
    写代码不要太死板
        20
    geelaw   36 天前 via iPhone
    第三种叫做 branch/jump table。
        21
    woscaizi   36 天前 via iPhone
    第三种是 查表法?
        22
    Xbluer   36 天前
    @tomoya92 #10 这里几乎不用考虑性能问题。
        23
    stevenkang   36 天前
    @sun2920989 这里应该可以不限语言,各个语言都可以这样写。put 的时候是初始化 type 和处理的映射,可以用多种方式初始化,不一定 new。

    @kkkkkrua 对,加上 spring 的一些特性,写出来更优雅。这里没有专门突出 spirng 是方便其他语言的使用者也可以参考、讨论研究。

    @jadec0der 表驱动法,优势是不是更方便增、减 type 以及热插拔?
    @pastgift 对,灵活应用更重要。这里探讨一下这三种方式也是比较各自的优缺点,方便在使用时灵活应对。

    @geelaw C 语言里面的知识吗?
        24
    lllllliu   36 天前
    EventBus/Notification Center 可以么。 对于多特性的同一种事件,我大部分用的都是用的 EventBus + Factory,或者干脆都变成一个独立的事件。。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2216 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 21ms · UTC 11:13 · PVG 19:13 · LAX 04:13 · JFK 07:13
    ♥ Do have faith in what you're doing.