类簇
类簇
是Foundation框架中广泛使用的设计模式。将一些私有、具体的子类组合在一个公共的、抽象的超类下面,以这种方法来组织类可以简化一个面向对象框架的公开架构,而又不减少功能的丰富性。
类簇是属于工厂设计模式的
举例应用
OC中的Number 可以表示很多类型的数值对象。其其实是一个抽象的基类,声明的方法一般都是操作其子类。 因为不同的数值类型可能有很多特征(可以从一个类型转换为另外一个类型,例如,可以描述其为字符串),所以在Number类里有很多方法可以用来描述这些特征,但是他们因为是不同类型,其存储的需求一定是不同的,所以Number类中并不声明实例变量去存储数值,在子类中声明这样的实例变量并在Number的API中获得
我们一般通过一下方法
NSNumber *aChar = [NSNumber numberWithChar:’a’];
NSNumber *anInt = [NSNumber numberWithInt:1];
NSNumber *aDouble = [NSNumber numberWithDouble:1.0];
其实生成的每个对象都属于不同的子类,虽然每个对象的类成员是隐藏的,但是抽象基类声明的接口是公共的。
常见公共基类类簇
也存在两个抽象公共类为类簇声明接口,但他们明确说明了两个点如何协作,其中一个公共的点声明所有类簇中对象都能响应的方法,另一点声明方法仅适合类簇对象内容能被修改的。
类簇的子类
如果发现类簇并没有提供你的问题的方法,这是可能需要一个子类。
- 需要创建一个文件存储而不是内存存储的数组对象,,就像要改变NSArray类簇的底层存储机制,那么必须创建一个子类
- 假设app需要在修改一些数据时提醒,此时没创建一个简单的类,将一个数据对象的基础框架定义。这个类的对象可以介入消息修改数据,拦截信息,代理,然后转发给嵌入式数据对象
总之,如果需要管理对象的存储就创建一个真正的子类。否则创建一个复合对象,一个标准的基础框架对象嵌在你自己的设计的一个对象。
创建类簇的子类
创建类簇的子类需要:
- 继承类簇的虚基类
- 定义自己的存储
- 重写父类的初始化方法
- 重写父类的原始方法
因为类簇的虚基类在类簇中仅有的公共访问点,所以只能继承虚基类,因此虽然可以继承其接口但是不能继承其实例变量,子类必须声明自己需要的实例变量,而且必须重写继承所有的方法,来访问对象的实例变量。这些方法叫做基元方法
一个类的基元方法来自接口的底层。
例如,NSArray
通过两个基元方法count:和objectAtIndex:
存储数据并且通过下标访问,作为基础其它导出方法可以实现。
因此,必须确保重写继承的基元方法,来去保证其它继承的所有派生方法可以正常运转,即使我们没有重写其它方法
子类应该声明其init、 +className
方法(如果其有实例变量的话),应该在自己的初始化方法中调用基类的指定初始化器。应该重写所有的其它继承的初始化方法并且实现,使其有合理的行为方法,
组合类
通过在自己设计的对象中植入类簇对象。创建一个组合复合对象。可以依靠类簇对象的功能,来截取复合对象要处理的消息。
复合对象继承自类簇的虚基类,作为子类,必须重写基类的基元方法,也可以重写导出方法(非必须).
示例:
测试验证对数组中对象的修改 保证其有效性
@interface ValidatingArray : NSMutableArray
{
NSMutableArray *embeddedArray;
}
+ (instancetype)validatingArray;
- (instancetype)init;
- (NSUInteger)count;
- (id)objectAtIndex:(NSUInteger)index;
- (void)addObject:(id)anObject;
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
- (void)removeLastObject;
- (void)removeObjectAtIndex:(NSUInteger)index;
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index;
@end
#import "ValidatingArray.h"
@implementation ValidatingArray
+ (instancetype)validatingArray {
return [[self alloc] init];
}
- (instancetype)init {
if (self = [super init]) {
embeddedArray = [NSMutableArray array];
}
return self;
}
- (NSUInteger)count {
return embeddedArray.count;
}
- (id)objectAtIndex:(NSUInteger)index {
return [embeddedArray objectAtIndex:index];
}
- (void)addObject:(id)anObject {
// 自定义验证代码
[embeddedArray addObject:anObject];
}
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject {
// 自定义验证
[embeddedArray replaceObjectAtIndex:index withObject:anObject];
}
- (void)removeLastObject {
// 自定义验证
[embeddedArray removeLastObject];
}
- (void)removeObjectAtIndex:(NSUInteger)index {
// 自定义验证
[embeddedArray removeObjectAtIndex:index];
}
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index {
// 自定义验证
[embeddedArray insertObject:anObject atIndex:index];
}
@end