TPFactory 0.0.1

TPFactory 0.0.1

测试测试
Lang语言 Obj-CObjective C
许可 MIT
发布最后发布2014年12月

未知的拥有者 维护。



TPFactory 0.0.1

TPFactory 是一个利用 Objective-C 运行时消除对头文件导入和长 if 语句需求的工厂模式实现。

您是否使用 TPFactory?

请告知我。

安装

Podfile(推荐)

将以下行添加到您的 podfile 并安装。

有关更多信息,请参阅 CocoaPods

pod "TPFactory", "~> 0.0.1"

在您的项目目录中运行 pod install

框架

  1. git clone https://github.com/mrevilme/TPFactory.git
  2. 打开 TPFactory.xcodeproj
  3. 构建 TPFactory 的归档目标
  4. 现在 TPFactory 文件夹内将会有一个 build/ 文件夹
  5. 将 TPFactory.framework 拖到您的项目中并开始使用 TPFactory。

子模块(如果您不知道自己在做什么,不建议使用)

  1. git submodule add https://github.com/mrevilme/TPFactory.git TPFactory
  2. 将 TPFactory.xcodeproj 拖到您的项目中
  3. 将 TPFactory 作为项目的构建依赖项
  4. 将 TPFactory 添加到项目的链接框架中
  5. 指定在 "Header Search Path" 中添加 "TPFactory/TPFactory/src/"

使用方法

首先,TPFactory 是由两种不同实现组成的,用于检测工厂中应存在的类。

  1. TPSubclassFactory

    会给出给定类实施的 TPBaseFactoryProtocol 协议的所有子类。

  2. TPProtocolFactory

    会给出运行时中实现了指定协议的所有类。

它们两者都使用一个协议 TPBaseFactoryProtocol 或其派生协议来标识应存在于工厂中的类。TPBaseFactoryProtocol 如下定义:

@protocol TPBaseFactoryProtocol <NSObject>
+ (NSInteger) priority;
+ (BOOL) canHandleObject: (id<NSObject>) object;
- (void) setObject: (id<NSObject>) object;
@end

TPSubclassFactory

  1. 假设您有以下模型类
@interface TPUser : TPModel
@end

@interface TPManager : TPUser
@end

@interface TPDeveloper : TPUser
@end
  1. 并且您想要能够获取代表管理器或开发人员的字典,并将此字典直接放入工厂中并获取最佳匹配的类。让我们重新定义我们的模型如下:
@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

TPProtocolFactory

如名称所示,而不是使用子类来寻找要添加的对象,这将查找特定的协议进行添加,并且还具有其他功能集。

  1. 让我们从定义我们要查找的协议开始,对于每个工厂实现,这都需要是唯一的。例如,你可能有一个用于模型,一个用于视图控制器,等等。
@protocol TPUserFactoryProtocol <TPProtocolFactoryProtocol>
@end
  1. 让我们重用我们之前示例中的模型,但有一些小变化,让我们向其中添加一种新的对象类型。
@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*****>]

捐赠

  1. 衍生它
  2. 改变它
  3. 发起拉取请求。

问题或疑问?

GitHub上发起一个问题。

致谢

维护者和开发者

许可证

TPFactory可在MIT许可下使用。有关更多信息,请参阅LICENSE文件。