iPhone开发重构:提取方法以调整抽象层次

     无论在iPhone开发还是学习的过程中都会看到一些不是很理想的代码,不可否认自己也在不断“贡献”着这类代码。面对一些代码的“坏味道”,重构显然是个有效的解决途径。《iPhone开发重构》系列就想总结和补充iPhone开发中经历的一些重构,其间可能会引用一些开源以及实际项目的代码,本着对技术的探求,冒昧之处还请作者多多见谅。

 

  写代码有时和说话一样,要体现层次感,可能是首先罗列要点,然后再逐点细化。但如果时而说要点,时而谈细节,就会造成听者理解上的障碍。如下的代码就会有这样的一个问题:

 

 

重构前:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    switch (indexPath.section) {
        case 0:
            return [[preferences objectAtIndex:indexPath.row] cell];
            break;
        case 1:
            {
                static NSString *CellIdentifier = @"wikiHowAboutCell";
                UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
                if (cell == nil) {
                    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
                }
                cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
                if (indexPath.row == 0) {
                    cell.text = @"About wikiHow App";
                } else {
                    cell.text = @"wikiHow Tips";
                }
                return cell;
            }
            break;
    }
    return nil;
}

  其中,Case 0和Case 1之间严重失衡,Case 0隐藏了创建的细节,而Case 1则是将其暴露无遗。抽象层次的差别造成了平衡感地缺少以及理解代码时的“颠簸”。重构后代码如下:

 

重构后:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = nil;
    NSUInteger sectionIndex = indexPath.section;
    if (sectionIndex == 0) {
        cell = [[preferences objectAtIndex:indexPath.row] cell];
    }
    else if(sectionIndex == 1) {
        cell = [self prepareCellForTable: tableView withRowIndex:indexPath.row];
    }

    return cell;
}

 

- (UITableViewCell *)prepareCellForTable: (UITableView *) tableView withRowIndex:(NSUInteger)index {
    static NSString *CellIdentifier = @"wikiHowAboutCell";

    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    if (index == 0) {
        cell.text = @"About wikiHow App";
    } else {
        cell.text = @"wikiHow Tips";
    }
    return cell;
}

 

    这样,理解代码时候如果只关注梗概就可以关注- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath,如果需要知道创建Cell的细节就可以看下- (UITableViewCell *)prepareCellForTable: (UITableView *) tableView withRowIndex:(NSUInteger)index。两个不同抽象层次上的函数形成的是一种代码的层次感以及平衡感。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值