美文网首页
以“类族模式”隐藏实现细节

以“类族模式”隐藏实现细节

作者: 名扬丶四海 | 来源:发表于2016-04-29 16:35 被阅读82次

    “类族”是一种很有用的模式,可以隐藏“抽象基类”背后的实现细节,OC系统框架中普遍使用此模式。比如UIKit中就有一个名为UIButton的类,创建按钮,则可以调用下面这个类方法:

     + (UIButton *)buttonWithType:(UIButtonType)type;
    

    该方法所返回的对象,其类型取决于传入的按钮类型,然而不管返回什么类型的对象,他们都继承同一个基类:UIButton,这么做的意义在于:UIButton类的使用者无需关心创建出来的按钮具体属于哪个子类,也不用考虑按钮的绘制方式等实现细节。

    我们可以把按钮的绘制逻辑都放在一个类里,并根据按钮类型来切换:

    - (void)drawRect:(CGRect)rect {
      if (_type == TypeA) {
       // Draw TypeA button 
     } else if (_type == TypeB) {
        // Draw TypeB button  
     }
    }
    

    这样写现在看上去还算简单,然而,若是需要依据按钮类型来切换的绘制方法有很多种,那么久麻烦了。很多优秀的程序员会将这种代码重构为多个子类,把各种按钮所用的绘制方法放到相关的子类中,不过,这么做需要用户知道各个子类才行,此时应该使用”类族模式“。

    “类族模式”可以灵活应对多个类,将他们的实现细节隐藏在抽象基类后面,以保持接口简洁,用户无需自己创建子类实例,只需调用基类方法来创建即可。

    创建类族

    废话不多说,直接举个例子:

    typedef NS_ENUM(NSUInteger, CWGEmployeeType) {
      CWGEmployeeTypeDeveloper,
      CWGEmployeeTypeDesigner,
      CWGEmployeeTypeFinance,
    }
    @interface CWGEmployee : NSObject
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, assign) NSUInteger salary;
    
    // 创建对象
    +(CWGEmployee *)employeeWithType : (CWGEmployeeType)type;
    
    // 让对象做工作
    - (void)doADaysWork;
    @end
    
    @implementation CWGEmployee
    
    +(CWGEmployee *)employeeWithType : (CWGEmployeeType)type {
      switch (type) {
        case CWGEmployeeTypeDeveloper:
                return [CWGEmployeeDeveloper new];
                break;
        case CWGEmployeeTypeDesigner:
                return [CWGEmployeeDesigner new];
                break;
        case CWGEmployeeTypeFinance:
                return [CWGEmployeeFinance new];
                break;
      }
    }
    
    - (void)doADaysWork {
      // Subclasses implement this.
    }
    @end
    

    每个“实体子类”都继承基类,例如:

    @interface CWGEmployeeDeveloper : CWGEmployee
    @end
    
    @implementation CWGEmployeeDeveloper
    - (void)doADaysWork {
        [self writeCode];
    }
    @end
    ```
    在这个例子中,基类实现了一个“类方法”,该方法根据待创建的雇员类别分配好对应的雇员类实例。这种“工厂模式”是创建类族的办法之一。
    还有一点需要注意:`如果对象所属的类位于某个类族中,那么在查询类型信息是就要当心了,你可能觉得自己创建了某个类的实例,然而实际上创建的确实其子类的实例。在Employee这个例子中, [employee isMemberOfClass:[CWGEmployee class]]似乎会返回YES,但是发回的确实NO,因为employee并非Employee类的实例,而是其某个子类的实例。`
    
    ###总结:
    - 类族模式可以吧实现细节隐藏在一套简单的公共接口后面。
    - 系统框架中经常使用类族。
    - 从类族的公共抽象基类中基础子类是要当心,若是有开发文档,则应该首先阅读。

    相关文章

      网友评论

          本文标题:以“类族模式”隐藏实现细节

          本文链接:https://www.haomeiwen.com/subject/cvahrttx.html