(九) [OC高效系列]尽量使用类族模式来隐藏细节

1.解读一下标题

就是将同一类型不同细节的逻辑放在子类中,而基类和所有子类统称为类族。我自己理解的定义,不喜勿喷。

2.先举一个没有用类族模式的小例子。

Person类有两个类型 Teacher、Student。当吃饭的时候,显示老师在吃饭和学生在吃饭。代码如下:

@interface Person : NSObject

@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *num;
@property (nonatomic,assign) PersonType type;
+ (instancetype)personWithType:(PersonType)type;

- (void)eat;

@end
@implementation Person

+ (instancetype)personWithType:(PersonType)type{
    Person * p = [[Person alloc] init];
    p.type = type;
    return p;
}

- (void)eat{
    switch (self.type) {
        case PersonTypeStudent:
            NSLog(@"学生在吃饭");
            break;
        case PersonTypeTeacher:
            NSLog(@"老师在吃饭");
            break;
    }
}
@end

使用情景代码

    Person * p = [Person personWithType:(PersonTypeTeacher)];
    [p eat]; //老师在吃饭
    
    Person * p1 = [Person personWithType:(PersonTypeStudent)];
    [p1 eat]; //学生在吃饭

这样是将所有的逻辑都写在这一个类中,当类型更多的时候,比如还有农民、医生、商人、官员等等,switch分支就会越来越多,当每种类型的逻辑再复杂点,eat方法就越来越复杂。

3.使用类族模式,Person类衍生两个子类Teacher、Student

Person基类

@interface Person : NSObject

@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *num;
@property (nonatomic,assign) PersonType type;
+ (instancetype)personWithType:(PersonType)type;

- (void)eat;

@end

@implementation Person

+ (instancetype)personWithType:(PersonType)type{
    switch (type) {
        case PersonTypeStudent:
            return [[Student alloc] init];
            break;
            
        case PersonTypeTeacher:
            return [[Teacher alloc] init];
            break;
    }
}

- (void)eat{
    
}

@end

Student类

@interface Student :Person

@end
@implementation Student

- (void)eat{
    NSLog(@"学生在吃饭");
}

@end

Teacher类

@interface Teacher :Person

@end
@implementation Teacher

-(void)eat{
    NSLog(@"老师在吃饭");
}

@end

使用情景代码

    Person * p = [Person personWithType:(PersonTypeTeacher)];
    [p eat]; //老师在吃饭
    
    Person * p1 = [Person personWithType:(PersonTypeStudent)];
    [p1 eat]; //学生在吃饭

可见使用时代码没有变,但是类中的逻辑被分割到子类中,当再加新的类型,就再增加新的子类就好了,基类基本无需改变,只需要在personWithType方法中增加一点判断语句就行了。逻辑更加清晰。更容易维护。
其实这基本上就是工厂模式。Java中经常用这种模式再加上反射,有的时候personWithType这类的方法都基本无需改变。

4.Cocoa中的类族

Cocoa中其实有许多类族。UIButton,还有大部分的collection类都是类族。

以NSArray为例

 NSArray *array = @[@1,@2];
 NSLog(@"%@",[array class]); //**__NSArrayI**

可见array的实际类型是__NSArrayl而不是NSArray本身。

5.判断类是否在一个类族中。

以下代码的条件将永远无法达成

if([array class] == [NSArray class]){
  //不会执行
}

类族的正确判断方式

if([array isKindOfClass:[NSArray class]]){
  //会执行
}

6.新增Cocoa中类似NSArray这样的子类要遵守的几点规则

  • 子类应该继承自类中中的基类。
  • 子类应该定义自己的数据存储方式。
  • 子类应该复写超类文档中指明要复写的方法。(因为OC中没有抽象方法的概念)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 34,561评论 18 399
  • 以 '类族模式' 隐藏实现细节 '类族' 是一种很有用的模式 (也叫做 '类别方法'), 可以隐藏 '抽象基类 '...
    dingzhijie阅读 496评论 0 3
  • 2014年的苹果全球开发者大会(WWDC),当Craig Federighi向全世界宣布“We have new ...
    yeshenlong520阅读 2,393评论 0 9
  • 1.objective-c常见面试题:1、**OC **语言的基本特点OC 语言是 C 语言的一个超集,只是在 C...
    LZM轮回阅读 1,021评论 0 3
  • 让自己强大起来的方式有很多种 我在努力变好 无论现在境遇如何 我都要 认认真真的过好每一天 每一小时 每一分钟 每一秒
    杜奇迹阅读 312评论 0 0

友情链接更多精彩内容