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

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

作者: 修行猿 | 来源:发表于2016-08-12 20:44 被阅读116次

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中没有抽象方法的概念)

相关文章

网友评论

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

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