TPFactory 是一个利用 Objective-C 运行时消除对头文件导入和长 if 语句需求的工厂模式实现。
请告知我。
将以下行添加到您的 podfile 并安装。
有关更多信息,请参阅 CocoaPods
pod "TPFactory", "~> 0.0.1"
在您的项目目录中运行 pod install
首先,TPFactory 是由两种不同实现组成的,用于检测工厂中应存在的类。
TPSubclassFactory
会给出给定类实施的 TPBaseFactoryProtocol 协议的所有子类。
TPProtocolFactory
会给出运行时中实现了指定协议的所有类。
它们两者都使用一个协议 TPBaseFactoryProtocol 或其派生协议来标识应存在于工厂中的类。TPBaseFactoryProtocol 如下定义:
@protocol TPBaseFactoryProtocol <NSObject>
+ (NSInteger) priority;
+ (BOOL) canHandleObject: (id<NSObject>) object;
- (void) setObject: (id<NSObject>) object;
@end
@interface TPUser : TPModel
@end
@interface TPManager : TPUser
@end
@interface TPDeveloper : TPUser
@end
@interface TPUser : TPModel
@end
@interface TPManager : TPUser<TPBaseFactoryProtocol>
@end
@interface TPDeveloper : TPUser<TPBaseFactoryProtocol>
@end
和或实现
用户
@implementation TPUser
@end
开发者
@implementation TPDeveloper
+ (NSInteger) priority {
return 0;
}
+ (BOOL) canHandleObject: (id<NSObject>) object {
id value = nil;
if ( (value = [object isKindOfClass:[NSDictionary class]] ) ) {
return [[value objectForKey: @"role"] isEqualToString: @"developer"] );
}
return NO;
}
- (void) setObject: (id<NSObject>) object {
[self parseDictionary: object];
}
@end
经理
@implementation TPManager
+ (NSInteger) priority {
return 1;
}
+ (BOOL) canHandleObject: (id<NSObject>) object {
id value = nil;
if ( (value = [object isKindOfClass:[NSDictionary class]] ) ) {
return [[value objectForKey: @"role"] isEqualToString: @"manager"] );
}
return NO;
}
- (void) setObject: (id<NSObject>) object {
[self parseDictionary: object];
}
@end
现在我们已经使我们的类为 TPSubclassFactory 类型的工厂做好了准备。让我们创建一个子类工厂的实例并使用它。
// Create a instance of the factory with the TPUser class as the root class and default options
TPSubclassFactory *userFactory = [[TPSubclassFactory alloc] initWithClass: NSClassFromString(@"TPUser") andOptions: TPProtocolFactoryDefaultOptions];
// Create two dictionaries that we can test it out with
NSDictionary *fakeDeveloperDictionary = @{@"role":@"developer"};
NSDictionary *fakeManagerDictionary = @{@"role":@"manager"};
// Now create a instance with the developer dictionary
id<NSObject> developer = [userFactory createInstanceForObject:fakeDeveloperDictionary];
// Now create a instance with the manager dictionary
id<NSObject> manager = [userFactory createInstanceForObject:fakeManagerDictionary];
NSLog(@"Developer: %@", NSStringFromClass([developer class]));
NSLog(@"Manager: %@", NSStringFromClass([manager class]));
将输出
User: TPDeveloper
Manager: TPManager
如名称所示,而不是使用子类来寻找要添加的对象,这将查找特定的协议进行添加,并且还具有其他功能集。
@protocol TPUserFactoryProtocol <TPProtocolFactoryProtocol>
@end
@interface TPManager : TPUser<TPUserFactoryProtocol>
@end
@interface TPDeveloper : TPUser<TPUserFactoryProtocol>
@end
@interface TPGroup : TPModel<TPUserFactoryProtocol>
@property(nonatomic,strong) NSArray *users;
@end
以下是实现细节
开发者
@implementation TPDeveloper
+ (NSInteger) priority {
return 0;
}
+ (BOOL) canHandleObject: (id<NSObject>) object {
id value = nil;
if ( (value = [object isKindOfClass:[NSDictionary class]] ) ) {
return [[value objectForKey: @"role"] isEqualToString: @"developer"] );
}
return NO;
}
- (void) setObject: (id<NSObject>) object {
[self parseDictionary: object];
}
+ (NSInteger) factoryType {
return 1;
}
@end
经理
@implementation TPManager
+ (NSInteger) priority {
return 1;
}
+ (BOOL) canHandleObject: (id<NSObject>) object {
id value = nil;
if ( (value = [object isKindOfClass:[NSDictionary class]] ) ) {
return [[value objectForKey: @"role"] isEqualToString: @"manager"] );
}
return NO;
}
- (void) setObject: (id<NSObject>) object {
[self parseDictionary: object];
}
+ (NSInteger) factoryType {
return 1;
}
@end
分组
@implementation TPGroup
+ (NSInteger) priority {
return 2;
}
+ (BOOL) canHandleObject: (id<NSObject>) object {
id value = nil;
if ( (value = [object isKindOfClass:[NSDictionary class]] ) ) {
return [[value objectForKey: @"role"] isEqualToString: @"group"] );
}
return NO;
}
- (void) setObject: (id<NSObject>) object {
// lets not do anything right now.
}
+ (NSInteger) factoryType {
return 1;
}
@end
现在我们再次设置了我们的对象。这次让我们做一个简单示例,演示如何将工厂作为一个单例来使用。
@interface TPObjectFactory : TPProtocolFactory
+ (id) shared;
@end
@implementation TPObjectFactory
TPPROTOCOLFACTORY_SINGELTON_DEFAULT(TPObjectFactory, @protocol(TPUserFactoryProtocol));
@end
#import "TPObjectFactory.h"
// Create two dictionaries that we can test it out with
NSDictionary *fakeDeveloperDictionary = @{@"role":@"developer"};
NSDictionary *fakeManagerDictionary = @{@"role":@"manager"};
NSDictionary *fakeGroupDictionary = @{@"role":@"group", @"users":@[fakeDeveloperDictionary,fakeManagerDictionary]};
// Now create a instance with the developer dictionary
id<NSObject> developer = [[TPObjectFactory shared] createInstanceForObject:fakeDeveloperDictionary];
// Now create a instance with the manager dictionary
id<NSObject> manager = [[TPObjectFactory shared] createInstanceForObject:fakeManagerDictionary];
// Now create a instance with the group dictionary
id<NSObject> group = [[TPObjectFactory shared] createInstanceForObject:fakeGroupDictionary];
NSLog(@"Developer: %@", NSStringFromClass([developer class]));
NSLog(@"Manager: %@", NSStringFromClass([manager class]));
NSLog(@"Group: %@", NSStringFromClass([group class]));
NSLog(@"Group users: %@", [group users]);
将输出
User: TPDeveloper
Manager: TPManager
Group: TPGroup
Group users: nil
现在我们对这个工厂做更多的事情。记住我们没有做任何事情来实现分组模型。这就要开始改变了。
分组
#import "TPObjectFactory.h"
@implementation TPGroup
+ (NSInteger) priority {
return 2;
}
+ (BOOL) canHandleObject: (id<NSObject>) object {
id value = nil;
if ( (value = [object isKindOfClass:[NSDictionary class]] ) ) {
return [[value objectForKey: @"role"] isEqualToString: @"group"] );
}
return NO;
}
- (void) setObject: (id<NSObject>) object {
if ( [object isKindOfClass:[NSDictionary class]] ) {
id value = nil;
if ( (value = [object objectForKey:@"users"]) && [value isKindOfClass:[NSArray class]]) {
NSMutableArray *_users = [NSMutableArray arrayWithCapacity: [value count]];
for(NSDictionary *user in value) {
[_users addObject:[[TPObjectFactory shared] createInstanceForObject:user]];
}
[self setUsers:[_users copy]];
}
}
}
+ (NSInteger) factoryType {
return 1;
}
@end
现在我们的示例将输出以下内容
User: TPDeveloper
Manager: TPManager
Group: TPGroup
Group users: [<TPDeveloper 0x*****>,<TPManager 0x*****>]
在GitHub上发起一个问题。
TPFactory可在MIT许可下使用。有关更多信息,请参阅LICENSE文件。