Effective Objective-C 2.0 第9条:以“类族模式”隐藏实现细节

类族模式

“类族”是一种很有用的模式,可以隐藏“抽象基类背后的实现细节”。Objective-C的系统框架中普遍使用此模式。如果想创建一个按钮,UIKit中就有一个名为“UIButton”的类,想创建按钮,需要调用“类方法”

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

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

对于开始问题,可以把各种按钮的绘制逻辑放在一个类里,并根据按钮类型来切换:

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

这样写现在看上去很简单,然而,若是需要依赖按钮类型来切换的绘制方式有很多种,那么久会变得很麻烦了。此时应该使用“类族模式”,该模式可以灵活对应多个类,将它们的实现细节隐藏在抽象基类后面,以保持接口简洁。用户无需创建子类实例,只需调用基类方法类来创建即可。

创建类族

假设有个雇员的类,每个“雇员”都有名字和薪水这两个属性。管理者可以命令其执行日常工作。可是各个雇员的工作内容却不同。

首先定义抽象基类

typedef NS_ENUM(NSUInteger, EOCEmployeeType) {
    EOCEmployeeTypeDeveloper,
    EOCEmployeeTypeDesigner,
    EOCEmployeeTypeFinance,
}

@interface EOCEmployee : NSObject
@property (copy) NSString* name;
@property NSUInteger salary;

+ (EOCEmployee*)employeeWithType:(EOCEmployeeType)type;

- (void)doADaysWork;

@end

@implementation EOCEmployee

+ (EOCEmployee*)employeeWithType:(EOCEmployeeType)type {
    switch(type) {
        case EOCEmployeeTypeDeveloper:
            return [EOCEmployeeDeveloper new];
            break;
        case EOCEmployeeTypeDesigner:
            return [EOCEmployeeDesigner new];
            break;
        case EOCEmployeeTypeFinance:
            return [EOCEmployeeFinance new];
            break;
    }
}

- (void)doADaysWork {
    //subclasses implement this
}
@end

每个实体子类都从基类继承而来,例如

@interface EOCEmployeeDelveloper : EOCEmployee
@end

@implementation EOCEmployeeDelveloper
- (void)doADayWork {
    [self writeCode];
}
@end

基类实现了一个“类方法”,该方法根据待创建的雇员分类分配好对应的雇员类实例。这种“工厂模式”是创建类族的办法之一。

OC这门语言没办法指明某个基类是“抽象的”。于是,开发者通常会在文档中指明类的用法。这种情况下,基类接口一般都没有声明init的成员方法,这暗示该类的实例也许不应该由用户直接创建。

Cocoa中的类族

我们经常需要向类族中新增子实体,不过这么做需要留意,在Employee这个例子中,若是没有“工厂方法”的源代码,那就无法向其中新增雇员类别了。然而对于Cocoa中NSArray这样的类族磊说,还是有办法新增子类的,但是需要遵守几条原则。

  • 子类应该继承自类族中的抽象基类。
  • 子类应该定义自己的数据存储方式。
    我们以为NSArray会为我们保存对象,但是要记住,NSArray本身只不过是包在其他隐藏对象外面的壳,他仅仅定义了所有数组都需要具备的一些接口。
  • 子类应当复写超类文档中指明需要复写的方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值