设计模式-简单工厂模式+反射机制

写在前面

上一篇工厂模式我们了解了简单工厂模式与工厂模式各自的优缺点,那么有没有一种设计思路可以

  • 能扩展新的运算模式
  • 不用去直接修改工具类
  • 不用给新的扩展类新增工具类

当然是可以的,这就是本文的价值

了解OC层面的反射机制

Objective-C 反射篇
Objective-C语言中的OC对象,都继承自NSObject类。这个类为我们提供了一些基础的方法和协议,我们可以直接调用从这个类继承过来方法。这里的反射方法,就在NSObject和Foundation框架中,不涉及runtime部分。

获取Class对象

Class对象其实本质上就是一个结构体,这个结构体中的成员变量还是自己,这种设计方式非常像链表的数据结构。

typedef struct objc_class *Class;
struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;                                  
}

可以直接用一个实例对象或类对象,直接调用Class方法,都可以获取Class对象。

反射方法

系统Foundation框架为我们提供了一些方法反射的API,我们可以通过这些API执行将字符串转为SEL等操作。由于OC语言的动态性,这些操作都是发生在运行时的。

// SEL和字符串转换
FOUNDATION_EXPORT NSString *NSStringFromSelector(SEL aSelector);
FOUNDATION_EXPORT SEL NSSelectorFromString(NSString *aSelectorName);
// Class和字符串转换
FOUNDATION_EXPORT NSString *NSStringFromClass(Class aClass);
FOUNDATION_EXPORT Class __nullable NSClassFromString(NSString *aClassName);
// Protocol和字符串转换
FOUNDATION_EXPORT NSString *NSStringFromProtocol(Protocol *proto) NS_AVAILABLE(10_5, 2_0);
FOUNDATION_EXPORT Protocol * __nullable NSProtocolFromString(NSString *namestr) NS_AVAILABLE(10_5, 2_0);

通过这些方法,我们可以在运行时选择创建那个实例,并动态选择调用哪个方法。这些操作甚至可以由服务器传回来的参数来控制,我们可以将服务器传回来的类名和方法名,实例为我们的对象。

// 假设从服务器获取JSON串,通过这个JSON串获取需要创建的类为ViewController,并且调用这个类的getDataList方法。
Class class = NSClassFromString(@"ViewController");
ViewController *vc = [[class alloc] init];
SEL selector = NSSelectorFromString(@"getDataList");
[vc performSelector:selector];

反射机制的使用

简单工厂模式的工具类写法如下,这种每新增一种运算模式,就要在工具类里增加一个分支,不仅违背了开放-封闭原则,还要每次做多次判断,及其不友好。

@implementation ZYCountTool

+ (ZYCount *)creatCountForOperation:(NSString *)operationStr
{
    if ([operationStr isEqualToString:@"+"]) {
        return [[ZYCountAdd alloc] init];
    }
    else if ([operationStr isEqualToString:@"-"]) {
        return [[ZYCountSubtractor alloc] init];
    }
    else if ([operationStr isEqualToString:@"*"]) {
        return [[ZYCountMuli alloc] init];
    }

    return [[ZYCountDivision alloc] init];
}
@end

反射机制的写法如下,工具类根据传入的类名,生成对应的运算类,完成运算。新增运算模式时只需要扩展运算类,不用新增对应的子工具类,不用修改父工具类,直接在客户端传入运算类名完成调用。

@implementation ZYCountTool
/**
 @param operationStr 运算类的类名
 */
+ (ZYCount *)creatCountForOperation:(NSString *)operationStr
{
    Class class = NSClassFromString(operationStr);

    ZYCount *count = [[class alloc] init];

    return count;
}
@end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值