类簇

2023-04-18  本文已影响0人  程序狗

类簇是一种设计模式,就是公共抽象父类对多个私有的具体子类进行分组,以这种方式对类进行分组简化了面对对象框架的公共可见体系结构,是基于抽象工厂设计模式设计的。
什么是抽象工厂模式。
工厂模式属于创建型模式,可以分为简单工厂模式、工厂模式和抽象工厂模式
简单工厂模式:根据传入的参数返回不同的实例


image.png

工厂模式: 让一个类的实例化延迟到子类,即factory类由子类实现,一个对象对应一个factory子类


image.png
抽象工厂模式:提供一个创建一系列相关或者互相依赖对象的接口,而无需指定它们具体的类。(在抽象工厂里面,每一个具体工厂都提供了多个工程方法用于产生不同类型的对象)
image.png

工厂模式的好处
1.解耦,创建的代码和使用分开
2.代码复用,简化实例化代码
3.容易扩展或修改

以NSArray举例

id obj1 = [NSArray alloc];        //__NSPlaceholderArray
id obj2 = [NSMutableArray alloc]; //__NSPlaceholderArray
id obj3 = [obj1 init];            //__NSArray0
id obj4 = [obj2 init];            //__NSArrayM

alloc 之后NSArray和NSMutableArray 都是生成__NSPlaceholderArray对象,然后init方法中生成__NSArray0和__NSArrayM的具体子类。在这个过程中__NSPlaceholderArray可以理解为是一个抽象工厂,而init则是抽象工厂的子类实例化过程
要实现这个过程,肯定会有个变量去存储它是由哪个类alloc出来,然后在init过程中根据这个变量来生成对应的子类

static __NSPlaceholderArray *GetPlaceholderForNSArray() {
    static __NSPlaceholderArray *instanceForNSArray;
    if (!instanceForNSArray) {
        instanceForNSArray = [__NPlaceholderArray alloc];
    }
    return instanceForNSArray;
}

static __NSPlaceholderArray *GetPlaceholderForNSMutableArray() {
    static __NSPlaceholderArray *instanceForNSMutableArray;
    if (! instanceForNSMutableArray) {
        instanceForNSMutableArray = [__NPlaceholderArray init];
    }
    return instanceForNSMutableArray;
}

//NSArray实现  
+(id)alloc {
    if(self == [NSArray class]) {
        return GetPlaceholderForNSArray;
    } else {
        return [super alloc]; 
    }
}

//NSMutableArray实现  
+(id)alloc {
    if(self == [NSMutableArray class]) {
        return GetPlaceholderForNSMutableArray;
    } else {
        return [super alloc]; 
    }
}

//__NSPlaceholderArray 实现  
-(id)init {
    if (self == GetPlaceholderForNSArray) {
        self = [[__NSArray0 alloc] init];
    } else if (self == GetPlaceholderForNSMutableArray) {
        self = [[__NSArrayM alloc] init];
    } else {
        self = [super init];
    }
    return self;
}

验证可以用以下代码

  for (NSInteger i = 0; i< 10; i++) {
        NSLog(@"%p",[NSMutableArray alloc]);
    }
    for (NSInteger i = 0; i< 10; i++) {
        NSLog(@"%p",[NSArray alloc]);
    }

所以我们在做集合类的安全气垫处理时,需要通过反射拿对应的子类。例如

Class __NSArrayM = NSClassFromString(@"__NSArrayM");
上一篇下一篇

猜你喜欢

热点阅读