zoukankan      html  css  js  c++  java
  • ios

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

    在iPhone开发的过程中经常会遇到根据不同的Table行或者标识符推入不同 的Controller的需要,一个最直接的实现就是硬编码,通过if…else if…else 或者switch…case…实现,代码如下:

    重构前:

    - (void)pushViewControllerWithIdentifier:(NSString *)identifier 
    
    animated:(BOOL)animated {
        if ([identifier 
    
    isEqualToString:@"Article"]) {
            viewController = 
    
    [[WHArticleViewController alloc] initWithIdentifier:identifier];
       
    
     } else if ([identifier isEqualToString:@"SurvivalKit"]) 
    
    {
            viewController = [[WHSurvivalKitViewController alloc] 
    
    init];
        } else if ([identifier 
    
    isEqualToString:@"Search"]) {
            viewController = 
    
    [[WHSearchViewController alloc] initWithIdentifier:identifier];
        
    
    } else if ([identifier isEqualToString:@"Featured"]) {
       
    
         viewController = [[WHFeaturedViewController alloc] 
    
    initWithIdentifier:identifier];
        } else if ([identifier 
    
    isEqualToString:@"Image"]) {
            viewController = 
    
    [[WHImageViewController alloc] initWithIdentifier:identifier];
        
    
    } else if ([identifier isEqualToString:@"Settings"]) {
       
    
         viewController = [[WHSettingsViewController alloc] init];
        
    
    }
        [self pushViewController:viewController 
    
    animated:animated];
        [viewController release];
    }

    其中的“坏味道”就是过多的条件分支判断以及在各个分支中雷同的代码。 在需要扩展的时候就要被迫修改代码,从而破坏了开放封闭原则。总结下规律后 觉得应该构建一个从identifier到对应的Controller名之间映射的表或者字典模 型。实现的时候通过setupModel构建映射表,然后具体使用的时候利用表进行映 射,重构代码如下:

    重构一:

    - (void) setupModel {
        if(self.model == nil) {
            
    
    self.model = [NSDictionary 
    
    dictionaryWithObjectsAndKeys:@"WHArticleViewController", 
    
    @"Article",
                          
    
    @"WHSurvivalKitViewController", 
    
    @"SurvivalKit",
                          
    
    @"WHSurvivalKitViewController", @"Search",
         
    
                     @"WHFeaturedViewController", 
    
    @"Featured",
                          
    
    @"WHImageViewController", @"Image",
                
    
              @"WHSettingsViewController", 
    
    @"Settings",
                          nil];
        }
    }
    
    
    - (void)pushViewControllerWithIdentifier:(NSString *)identifier 
    
    animated:(BOOL)animated {
        NSString *identifierNamespace = 
    
    [identifier identifierNamespace];
        NSString *controllerClassName 
    
    = [self.model objectForKey:identifierNamespace];
        Class klass = 
    
    NSClassFromString(controllerClassName);
        UIViewController 
    
    *viewController = [[klass alloc] initWithIdentifier:identifier];
       
    
     [self pushViewController:viewController animated:animated];
        
    
    [viewController release];
    }

    重构后,不仅避免了过多的条件分支而且清理了各个分支中的雷同代码。不 足就是表模型数据还是夹杂在代码中,因此希望通过plist文件隐藏这些和代码 无关的数据。重构代码如下:

    重构二:

    - (void) setupModel{
        if(self.model == nil) {
            
    
    NSString *plistFilePath = [[NSBundle mainBundle] 
    
    pathForResource:@"Model" ofType:@"plist"];
         
    
       self.model = [NSDictionary 
    
    dictionaryWithContentsOfFile:plistFilePath];
        }
    }
    - 
    
    (void)pushViewControllerWithIdentifier:(NSString *)identifier 
    
    animated:(BOOL)animated {
        //实现同“重构一”
    }

    现在,一切看上去还挺美的。不过可能一段时间后会发现,原来indentifier 和Controller名之间的映射是有规律的,所以可能根本不需要映射表。尝试一下 吧!

    重构三:

    - (void)pushViewControllerWithIdentifier:(NSString *)identifier 
    
    animated:(BOOL)animated {
        NSString *identifierNamespace = 
    
    [identifier identifierNamespace];
        NSString *controllerClassName 
    
    = [NSString stringWithFormat:@"WH%@ViewController", 
    
    identifierNamespace];
        Class klass = NSClassFromString
    
    (controllerClassName);
        UIViewController *viewController = 
    
    [[klass alloc] initWithIdentifier:identifier];
        [self 
    
    pushViewController:viewController animated:animated];
        
    
    [viewController release];
    }

    经过几个阶段的重构,代码不仅“瘦身”了,而且逻辑更清晰了。通过这样 一个从硬编码到模型到规律的过程,大家看到的应该不仅仅是不断改进的代码, 而且还会感觉到重构的迭代性和无止境吧!任何的设计和实现都只能是在某种情 境和阶段是合理的,而不存在一个永远完美的答案。

    来源: http://blog.csdn.net/lbj05/archive/2011/04/20/6336851.aspx

  • 相关阅读:
    oracle grant授权的理解
    SQL SERVER 2005 版本以上 CTE递归查询的实现
    常用的加密解密技术之——【加密原理】
    常用的汇编指令
    常用加密解密技术之——【DES算法实现过程分析】
    VC6.0编译器中混有.c文件时出现fatal error C1853错误解决办法
    C++ Primer读书笔记
    Shot(数学+物理题,不简单)
    [置顶] C++/C 数据类型的取值范围
    <fzu1922>非主流
  • 原文地址:https://www.cnblogs.com/ranger-jlu/p/3957110.html
Copyright © 2011-2022 走看看