设计模式之工厂:

来源:互联网 发布:怎么改变网络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"];

原创粉丝点击