如何完美的消除 if...else..或者 switch 这种代码,求大神给个思路。

2016-06-30 10:55:29 +08:00
 hyyy

举个例子,在 iOS 开发中,经常会遇到在设置 tableViewCell 时需要根据 indexPath 来设置不同 cell ,一般代码可能会是下面这个样子:

- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
    
    // 设置第一种 cell
    if (indexPath.section == 3 && indexPath.row != 2) {
        //  cell 代码
        return cell;
    }
    
    // 设置第二种 cell
    if (indexPath.section == 3 && indexPath.row == 2) {
        // cell 代码
        return cell;
    }
    
    // 设置其他 cell
    return cell;
}

当然,举的例子比较简单, if...else...也不多,这种场景在开发中很多,一般使用 if...else...或者 switch 时会使代码非常多,求大神们能不能给个思路,遇到这种场景尽量不要出现这种嵌套代码,最好给个实例膜拜膜拜 ^_^

16917 次点击
所在节点    程序员
86 条回复
vincentxue
2016-06-30 14:13:31 +08:00
看来 iOS 迫切需要一个为 UITableView 或者 UICollectionView 解决数据源封装的库。
sensui7
2016-06-30 14:22:34 +08:00
OO 中的 tell, don't ask 原则可以消除这种大量的 else , if else 多说明代码抽象的不好, 根据你的逻辑,可以采用相应的设计模式解决
lalalafq
2016-06-30 14:29:03 +08:00
所有的数据源逻辑(高度,点击,渲染)全部丢到一个 array ;基础的 tableView 委托永远只有大概 10 行左右;
绝壁高聚合,低耦合;产品想怎么改就怎么改;顺序啥的都是小问题。
JohnSmith
2016-06-30 14:33:48 +08:00
rust 中有个 match
skyoojaa
2016-06-30 15:05:24 +08:00
If...else...没法消除,但可以封装判断,让 if...else...里面的代码看起来简洁一些
realpg
2016-06-30 15:22:54 +08:00
我觉得这种代码很好
瞎搞弄得可维护性差才是大坑
iyeatse
2016-06-30 15:40:35 +08:00
dorentus
2016-06-30 15:41:54 +08:00
@realpg 在最前面加一行的话,要从上到下把数字都改掉,也叫可维护性好么……
so898
2016-06-30 15:56:52 +08:00
真要很多的话不应该是自定义 Cell ,然后把代码放到 Cell 里面去么?
如果说不能自定义 Cell ,那不是应该通过在外面建立 Cell 内容填充生成的方法来做到精简这一块的代码么?
missdeer
2016-06-30 16:38:21 +08:00
你看,用 OO 设计模式的时候到了,上面说不行的都不是那个年代过来的人
weirdyu
2016-06-30 16:53:45 +08:00
你这种按照行数来判断返回何种 cell 的方式不太好
zjyjer
2016-06-30 17:05:44 +08:00
1. 模式匹配
2. 设计一个状态机 每个分支里的代码抽象出一个函数异步调用之
programgou
2016-06-30 17:11:55 +08:00
我认为我们可以专门提供一个 indexPath 的接口,然后再提供一个 builder ,把实现了 indexPath 接口的类的实例传递给 builder , builder 就可以返回一个 cell 。这样无论你有多少种 indexPath ,只需要维护 builder ,而不会改变 tableView 的任何代码。当你觉得你现在的 builder 过于复杂的时候,你甚至可以为这个 builder 提供接口,这样你可以在不改变原来代码的基础上,替换掉原来的 builder 。总之,类与类建立关系要通过接口,这样就可以在不改变代码的基础上,换掉一个类。也就是换掉一个功能。

这里面涉及到一些设计模式的东西,不过楼主别怕,看不懂书建议去看源码,我博客上写过一个关于建构者模式的分析,你可以参考一下,不过要解决你的问题一个建构者模式肯定是不够的,还有工厂模式。
sablib
2016-06-30 17:13:05 +08:00
如果是 swift 的话,就用 enum 了。
billion
2016-06-30 17:29:57 +08:00
如果语言是 Python 的话,可以使用字典解决:
```
def a(para):
xxx

def b(para):
xxx

def c(para):
xxx

functionDict = {'a':a, 'b': b, 'c': c}

result = functionDict[name](para)
```
这样,当你需要使用 switch 或者 if ...else 来调用函数的时候,可以通过: functionDict('a')(para)这种方式调用函数。
chrisstyle
2016-06-30 17:36:22 +08:00
同 25 楼~
推荐
i4mszengg
2016-06-30 18:02:04 +08:00
我想应该不用故意写一些奇葩的逻辑,日后维护很痛苦的吧,如果 单个 if 的 condiftions 比较多,可以嵌套 if , 这样更容易懂些,日后好维护。
jasonlz
2016-06-30 18:25:42 +08:00
用状态机。
ooonme
2016-06-30 18:30:40 +08:00
@zjyjer 正解
djyde
2016-06-30 18:34:00 +08:00
程序之所以是程序,因为它能 if else

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/289282

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX