• 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。两个不同抽象层次上的函数形成的是一种代码的层次感以及平衡感。

    本文出自 “林家男孩” 博客,请务必保留此出处http://bj007.blog.51cto.com/1701577/545532

  • 相关阅读:
    python编程设计模式之接口类和抽象类
    python进阶之面向对象初识
    python进阶之异常处理
    python模块之包
    python模块之序列化模块
    python基础二 ---类型转换 ,字符串,列表,元祖,for,range,enumerate
    python基础一
    TCP协议的三次握手
    随机数Math.random()
    Vue.js内部响应式原理探究
  • 原文地址:https://www.cnblogs.com/simonshi2012/p/2269350.html
Copyright © 2020-2023  润新知