我们现在有一个参数 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()
从执行效率、可读性、可维护性等多个方面来看,哪种方式综合评分更高?
![]() | 1 z42514 2019-08-15 17:27:29 +08:00 我选三 |
![]() | 2 TomVista 2019-08-15 17:27:50 +08:00 20 种 type 可以排除 if else 了吧 |
![]() | 3 mara1 2019-08-15 17:35:55 +08:00 放到字典里,差不多就是 3 |
4 hmellochan 2019-08-15 17:40:48 +08:00 那么多类型,明显三好。 |
![]() | 5 Vegetable 2019-08-15 17:40:54 +08:00 2 和 3 在底层差不多是一样的吧,条件这么多我选 3. |
6 672795574 2019-08-15 18:05:57 +08:00 ![]() 1,2 我选 1,踩过忘记加 break 的坑(自己的问题) 3 应该是抽象过了,看着也有点符合开闭原则 因此理论上新加一个 type 和 Processor 不需要测试原来的逻辑。 |
![]() | 7 fuxiao11 2019-08-15 18:14:29 +08:00 via Android 3 其实是责任链模式的一种变形实现 |
![]() | 8 kkkkkrua 2019-08-15 18:21:36 +08:00 spring 直接 getBean("xxx_TYPE1").exec()不更好么, 其他方式直接 new 对应的实例,不用 if.. |
9 Justin13 2019-08-15 18:21:44 +08:00 via Android 当然是第三种字典啦。 |
10 tomoya92 2019-08-15 18:24:38 +08:00 via iPhone 性能上哪个最高呢 |
![]() | 11 sun2920989 2019-08-15 18:42:30 +08:00 没看出来是什么语言,但是确定第三种方法是在 get 时才去实例化的吗?看着写法有点担心 put 时直接 new 了. |
![]() | 12 autoxbc 2019-08-15 18:51:40 +08:00 2 好,switch 故意不写 break 也是一种写法 语句由上而下叠加执行,在需要共享一部分处理逻辑时有奇效。当然要防止别人打你 |
![]() | 13 ianva 2019-08-15 19:08:57 +08:00 表驱动 |
![]() | 14 jadec0der 2019-08-15 19:24:12 +08:00 第三种在代码大全 18 章叫「 表驱动法」 |
15 Leammin 2019-08-15 20:10:59 +08:00 via Android 少的时候 2,多的时候 3 |
![]() | 16 murmur 2019-08-15 20:13:26 +08:00 我投 gotoy 一票 |
17 ywcjxf1515 2019-08-15 20:41:19 +08:00 via iPad 谷歌搜 if 策略模式 map v2ex,或者搜 if 状态模式 map v2ex。 |
18 zw1one 2019-08-15 21:35:53 +08:00 via Android 如果你 if 里的条件全长这个样子,那肯定 3 好。如果 if 条件会突然多两个奇怪的判断,用 3 就不好改。 |
19 pastgift 2019-08-15 22:31:58 +08:00 2 到 5 个分支用,每个分支代码量中等( 20 行以内) if-else 3 到 10 个分支,每个分支代码量很少( 10 行以内) switch-case 2 个分支以上,每个分支代码量很多,表驱动方式 具体操作按个人喜好,项目要求,统一性洁癖,美观等因素调整 写代码不要太死板 |
![]() | 20 geelaw 2019-08-15 23:21:34 +08:00 via iPhone 第三种叫做 branch/jump table。 |
![]() | 21 woscaizi 2019-08-15 23:36:15 +08:00 via iPhone 第三种是 查表法? |
![]() | 23 stevenkang OP @sun2920989 这里应该可以不限语言,各个语言都可以这样写。put 的时候是初始化 type 和处理的映射,可以用多种方式初始化,不一定 new。 @kkkkkrua 对,加上 spring 的一些特性,写出来更优雅。这里没有专门突出 spirng 是方便其他语言的使用者也可以参考、讨论研究。 @jadec0der 表驱动法,优势是不是更方便增、减 type 以及热插拔? @pastgift 对,灵活应用更重要。这里探讨一下这三种方式也是比较各自的优缺点,方便在使用时灵活应对。 @geelaw C 语言里面的知识吗? |
![]() | 24 lllllliu 2019-08-16 10:12:19 +08:00 EventBus/Notification Center 可以么。 对于多特性的同一种事件,我大部分用的都是用的 EventBus + Factory,或者干脆都变成一个独立的事件。。 |