工厂方法模式
定义创建对象的接口,让子类决定实例化哪一个类,工厂方法使得一个类的实例化延迟到其子类.
*最初的定义出现于<设计模式>(Addison-Wesley,1994)
注意:我讲解的是静态工厂,它只能执行静态的方法,也就是类方法,似乎与工厂方法有些神识但也有区别.
先准备一个基类的数据模型
BaseModel.h + BaseModel.m
#import// 基类数据模型,为派生出的子类定义统一的接口(该基类所有的实现都为空实现)@interface BaseModel : NSObject+ (void)modelInfo;@end
#import "BaseModel.h"@implementation BaseModel+ (void)modelInfo{ NSLog(@"BaseModel");}@end
用两个类分别继承至该基类
NameModel.h + NameModel.m
#import "BaseModel.h"@interface NameModel : BaseModel+ (void)modelInfo;@end
#import "NameModel.h"@implementation NameModel+ (void)modelInfo{ if (self == [NameModel class]) { NSLog(@"NameModel"); }}@end
NewsModel.h + NewsModel.m
#import "BaseModel.h"@interface NewsModel : BaseModel+ (void)modelInfo;@end
#import "NewsModel.h"@implementation NewsModel+ (void)modelInfo{ if (self == [NewsModel class]) { NSLog(@"NewsModel"); }}@end
注意,这两个基类都重载了父类中的方法modelInfo
之后就来定义我们的工厂类了
ModelFactory.h + ModelFactory.m
#import@interface ModelFactory : NSObject+ (Class)classWithModel:(id)model;@end
#import "ModelFactory.h"#import "BaseModel.h"#import "NameModel.h"#import "NewsModel.h"@implementation ModelFactory+ (Class)classWithModel:(id)model{ Class modelClass = Nil; if ([model isKindOfClass:[NameModel class]]) { modelClass = [NameModel class]; } else if ([model isKindOfClass:[NewsModel class]]) { modelClass = [NewsModel class]; } else if ([model isKindOfClass:[BaseModel class]]) { modelClass = [BaseModel class]; } return modelClass;}@end
这样,一份完整的静态工厂相关的设计就出来了,不过这个静态工厂不是用来创建对象的,而是来识别对象的.
用途:
客户端(使用你封装代码的人)不关心你的基类到底派生出了多少种子类,它只关心,特定的子类返回特定的样式,知道这些就够了.他只会用这个基类指针从工厂中获取想要的东西,而你就必须得在工厂中去处理这些东西.客户端无需更改什么代码,一切的代码都在工厂中处理,客户端是不关心的.
注意细节:
1. 基类需要定义一些方法(公共的类方法接口)并空实现,子类继承之后按需要重载实现这些公共的接口,不实现也行.
2. 工厂中集中识别这些继承的对象,匹配出对象后返回想要的结果.
3. 添加了新的子类后需要更新工厂.