设计模式之工厂:
来源:互联网 发布:怎么改变网络vp6 编辑:程序博客网 时间:2024/05/17 13:38
转自:http://www.cnblogs.com/sunnyxx/archive/2012/04/27/2473146.html
程序中可能会出现大量的if-else或者switch-case来选择一系列类中的某个类进行操作,利用反射(Reflection)就可以避免这些重复判断工作。
反射在Java中封装了类来实现,在Objective-C里面要自己来实现,好在不是很难。
我们的目的是通过传入一个类名字符串,把字符串类名动态转化成类,并对类进行实例化和调用方法等操作。
OC的NSRuntime中提供了将Class name转化为Class的方法"NSClassFromString()"
NSClassFromString //方法原型Class NSClassFromString ( NSString *aClassName);
因此,我们就可以这样使用来动态获得一个类:
NSString * aClassName = @"SunnyClass";Class class = NSClassFromString(aClassName);
这样我们就能实例化这个类了:
id instance = [[class alloc] init];
如果需要使用方法,最好用reponseToSelector:来检测一下
if([instance reponseToSelector:@selector(aMethod)]){ [instance aMethod];}
这样就完成了反射调用的过程。
下面就是将反射利用到工厂模式里。
定义一个Fruit,和三种继承自Fruit的水果
@interface Fruit : NSObject- (void)show;@end@interface Apple : Fruit @end@interface Banana : Fruit @end@interface Pear : Fruit @end
实现部分,简单的show方法来打印
@implementation Fruit- (void)show{ NSLog(@"I'm a fruit");}@end@implementation Apple- (void)show{ NSLog(@"I'm an apple");}@end@implementation Banana- (void)show{ NSLog(@"I'm a banana");}@end@implementation Pear- (void)show{ NSLog(@"I'm a pear");}@end
如果使用传统的if-else分支判断的话,情况就会变得非常恶心,如果想再增加一个Orange类的话,不仅需要增加Orange类的代码,工厂的代码也要新增加else-if分支:
- (Fruit *)createFruitWithName:(NSString *)fruitName{ Fruit * theFruit; if ([fruitName isEqualToString:@"Apple"]) { theFruit = [[[Apple alloc] init] autorelease]; } else if ([fruitName isEqualToString:@"Banana"]) { theFruit = [[[Banana alloc] init] autorelease]; } else if ([fruitName isEqualToString:@"Pear"]) { theFruit = [[[Pear alloc] init] autorelease]; } return theFruit;}
但如果使用反射工厂的模式,情况就变得简单了许多,扩展性也会变得更好(反射输入的类名最好能来自于一个文件,这个文件规定了哪些字符串是可以作为参数传入的,这里就不考虑了)
@implementation FruitFactroy- (Fruit *)createFruitWithName:(NSString *)fruitName{ //通过string得到类的结构体 Class class = NSClassFromString(fruitName); //通过转化的class得到实例对象 Fruit * theFruit = [(Fruit *)[[class alloc] init] autorelease]; //调用对象方法 if ([theFruit respondsToSelector:@selector(show)]) { [theFruit show]; } //返回对象 return theFruit;}@end
工厂方法的调用
FruitFactroy * factroy = [[[FruitFactroy alloc] init] autorelease]; Fruit * apple = [factroy createFruitWithName:@"Apple"]; Fruit * banana = [factroy createFruitWithName:@"Banana"]; Fruit * pear = [factroy createFruitWithName:@"Pear"];
- 设计模式之工厂:
- 设计模式之工厂
- 设计模式之工厂
- 设计模式之工厂
- 设计模式之工厂
- 设计模式之工厂
- 设计模式之工厂
- 设计模式之工厂
- 设计模式之工厂设计
- 设计模式之工厂模式
- 设计模式之工厂模式
- 设计模式之工厂模式
- 设计模式之工厂模式
- 设计模式之工厂模式
- 设计模式之工厂模式
- 设计模式之---工厂模式
- 设计模式之工厂模式
- 设计模式之工厂模式
- 计算机网络复习
- 备份Linux分区
- 安卓控件APPwidget 一
- 编辑取gridview里的dropdownlist的值时"未将对象引用设置到对象的实例"
- 队列
- 设计模式之工厂:
- css的position
- 求多个字符串的最长公共子串
- 单元格中含有自动计算如何截取小数点
- N9破解无线密码
- HTML <a> 标签的 target 属性
- 清空ArrayList所引发的思考(List相关操作)
- 栈
- res: layout-finger 目录