什么是设计模式,先来看段度娘的话:编程
设计模式(Design pattern)是一套被反复使用、多数人知晓的、通过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构同样。设计模式
其实咱们不须要这么专业,在个人理解,设计模式就是一种规范化的编程习惯,养成了这样的思想与习惯,对咱们的代码,老是有好处了。框架
首先,工厂设计模式是建立对象的一种设计模式,一个严格意义上的工厂设计模式应该是一个纯虚的构造方法。由子类进行具体对象的建立,咱们能够这样理解:如今有一个珲少牌制造工厂,这个工厂能够制造多种交通工具,我大胆一些,假设它能够制造飞机,轮船。小汽车,公交车,出租出和自行车,那么,这些不一样的车种虽然功能和大类别统一,可是他们的个体差别也是天地之别,就好比我飞机一小时能够飞5000千米,自行车拼死了劲也不必定能骑20千米。因此,若是珲少这个大工厂要生产他们,也不可能把他们放在一块儿生产。一个比较明智的决定是,开立分厂,好比珲少飞机工厂专门生产飞机,珲少自行车工厂专门生产自行车。函数
好了,若是将咱们这种人类世界的思惟运用于程序世界,那么咱们能够经过工厂的这种思惟方式来将一些大类抽象为工厂,经过定义接口或者说是定义虚函数来规范这个大工厂的生产规模和流程,由其子类来具体实现这些方法,也就是由一个个小的分厂来明确的生产咱们须要的东西。这就是工厂设计模式的基本思路。工具
许多开发者或许并不在乎设计模式这个东西,咱们可能会想,我实现个人功能就能够了,你管我怎么设计呢。在这篇博客的开头就说到,在我理解中,设计模式就是一种编程习惯和规范,更是一种众多开发者摸索出来的经验,这就像农业上的套种间种和你随便种,哪种效率高,收成好,不言而喻。那么在软件设计中,工厂模式的应用在哪呢?atom
咱们先来体验一下在iOS开发中,一些使用工厂设计模式的系统类为咱们带来的便捷之处:spa
在iOS的Foundation框架中,类簇是一种经常使用的设计模式,他将一些相近的,私有的,具体的子类组合在一个实体的抽象类下面,我称这个抽象类为实体的,是由于和咱们交互的接口承载者,就是这个抽象大类。咱们平时经常使用的三大类,NSString,NSArray,NSDictionary都是类簇,咱们经过他们建立的对象都是其子类对象的实例化,并非他自己的实例化,咱们还经过上面的例子来理解,我买了一辆珲少小汽车,这两汽车的生产实际是在珲少汽车工厂生产的,可是我我的会依然认为,这是珲少工厂出产的汽车。咱们能够经过打印类名来验证:设计
NSString * str = [[NSString alloc]initWithCString:"2" encoding:0]; NSLog(@"%@",[str class]);
结果以下:代理
能够看到,真实的对象是NSString的子类__NSCFString进行实例化的。code
若是你经过NSString的事例仍是没法体会到类簇,也就是工厂设计模式的优点,那么下面这个例子你必定常常遇到:NSNumber。咱们在建立数字对象的时候,一般会这样考虑,若是是int值,我须要一个IntNumber的类,float值,我须要一个FloatNumber类,若是foundation框架真这么设计的话,那么你如今就痛苦了,你不只要记住好多这样类似的类,调用方法时也要相应的对象调其内的方法,这使开发者的开发变得更加繁琐,而且对于开发者来讲,我并不须要知道具体我建立了什么类,我只是想让他完成既定的方法。说的更通俗一点,仍是上面的制造工厂,使用者并不在意具体这个交通工具是哪一个地方生产出来的,只要它价钱和速度都是使用者预期的结果就行了。
经过上面的分析,咱们大体能够总结出工厂这种设计模式的应用场景:
(1)当一个类并不知道要建立的具体对象是什么,交由子类处理
(2)当一些类有类似的行为和结构,只是具体实现不一样时,能够抽象出工厂
(3)使用者并不在意具体类型,只在意接口约定的行为,而且这种行为有个体差别
一样是上面的例子,咱们来用代码模拟一下:
首先,咱们建立一个抽象的工程类,在其中建立一些私有的子类:
#import <Foundation/Foundation.h> //交通工具的枚举 typedef enum { car, boat, airport, bycicle, bus, taxi }ToolsName; //代理 @protocol TransPortationDelegate <NSObject> -(void)toHome:(Class)class; @end //抽象工厂类 @interface TramsPortationFactory : NSObject +(TramsPortationFactory*)buyTool:(ToolsName)tool; //共有的方法接口 -(int)shouldPayMoney; -(void)run; @property(nonatomic,strong)id<TransPortationDelegate>delegate; @end //具体实现的子类 @interface CarFactory : TramsPortationFactory @end @interface BoatFactory : TramsPortationFactory @end @interface AirportFactory : TramsPortationFactory @end @interface BycicleFactory : TramsPortationFactory @end @interface TaxiFactory : TramsPortationFactory @end @interface BusFactory : TramsPortationFactory @end
实现文件以下:
#import "TramsPortationFactory.h" @implementation TramsPortationFactory //实现的建立方法 +(TramsPortationFactory*)buyTool:(ToolsName)tool{ switch (tool) { case car: return [[CarFactory alloc]init]; break; case airport: return [[AirportFactory alloc]init]; break; case bycicle: return [[BycicleFactory alloc]init]; break; case boat: return [[BoatFactory alloc]init]; break; case taxi: return [[TaxiFactory alloc]init]; break; case bus: return [[BusFactory alloc]init]; break; default: break; } } -(int)shouldPayMoney{ return 0; } -(void)run{ [self.delegate toHome:[self class]]; } @end //各自类实现具体的行为 @implementation CarFactory -(int)shouldPayMoney{ return 50; } -(void)run{ [super run]; NSLog(@"car to home"); } @end @implementation AirportFactory -(int)shouldPayMoney{ return 1000; } -(void)run{ [super run]; NSLog(@"fly to home"); } @end @implementation BoatFactory -(int)shouldPayMoney{ return 300; } -(void)run{ [super run]; NSLog(@"boat to home"); } @end @implementation BusFactory -(int)shouldPayMoney{ return 10; } -(void)run{ [super run]; NSLog(@"bus to home"); } @end @implementation BycicleFactory -(int)shouldPayMoney{ return 0; } -(void)run{ [super run]; NSLog(@"run to home"); } @end @implementation TaxiFactory -(int)shouldPayMoney{ return 100; } -(void)run{ [super run]; NSLog(@"go to home"); } @end
这样,咱们的一个生产工厂就完成了,在外面,咱们只须要知道一个类,咱们的抽象父类,就能够实现个子类的行为,示例以下:
- (void)viewDidLoad { [super viewDidLoad]; TramsPortationFactory * tool = [TramsPortationFactory buyTool:car]; tool.delegate=self; [tool run]; NSLog(@"花了:%d钱",[tool shouldPayMoney]); TramsPortationFactory * tool2 = [TramsPortationFactory buyTool:airport]; tool2.delegate=self; [tool2 run]; NSLog(@"花了:%d钱",[tool2 shouldPayMoney]); } -(void)toHome:(Class)class{ NSLog(@"%@",NSStringFromClass(class)); }
能够看到,对于开发者,咱们并不知晓CarFactory类的存在,咱们只须要经过TramsPortationFactory类,就可以操做各类交通工具,达到咱们的需求。
专一技术,热爱生活,交流技术,也作朋友。
——珲少 QQ群:203317592