工厂模式算是开发中比较常见的设计模式,简单工厂模式,工厂模式和抽象工厂模式,都属于工厂模式。简单工厂模式(simple factory)是类的创建模式,静态工厂方法(static factory method)模式,简单工厂模式就是由一个工厂类根据传入的参数决定创建哪一种的产品类。简单工厂模式会包含过多的判断条件,维护起来不是特别方便,工厂模式是主要通过依赖倒置将类的实例化推迟到子类中,实现动态扩展。抽象工厂模式是一个对象产品家族,根据需求提供不同的对象。
简单工厂模式
之前的文章中写过一篇简单工厂模式,假设我们我有一个服装加工工厂,可以根据不同的需求生产不同的服饰,定义一个服装基类和工厂类:
@protocol DressProtocol <NSObject> @optional -(void)provideMaterial; @optional -(void)product; @end @interface Dress : NSObject<DressProtocol> @end
服装Dress子类ForeignDress:
@implementation ForeignDress -(void)provideMaterial{ NSLog(@"ForeignDress--准备原材料"); } -(void)product{ NSLog(@"ForeignDress--生产"); } @end
ChinaDress子类:
@implementation ChinaDress -(void)provideMaterial{ NSLog(@"ChinaDress---准备原材料"); } -(void)product{ NSLog(@"ChinaDress---生产"); } @end
工厂类Manufactor:
@protocol ManufactorProtocol <NSObject> @optional -(Dress *)createDress:(NSString *)type; @end @interface Manufactor : NSObject<ManufactorProtocol> -(void)start:(NSString *)type; -(void)simpleStart:(NSString *)type; -(void)startByCondition:(NSString *)type; @end
方法实现:
-(void)start:(NSString *)type{ if ([type isEqualToString:@"Foreign"]) { dress=[[ForeignDress alloc]init]; }else if([type isEqualToString:@"China"]){ dress=[[ChinaDress alloc]init]; } [dress provideMaterial]; [dress product]; } //博客园-FlyElephant 简单工厂 -(void)simpleStart:(NSString *)type{ dress=[ManuFactory dressInstance:type]; [dress provideMaterial]; [dress product]; }
方法调用:
Manufactor *factor=[[Manufactor alloc]init]; [factor start:@"Foreign"]; [factor simpleStart:@"China"]; NSLog(@"博客园-FlyElephant"); NSLog(@"http://www.cnblogs.com/xiaofeixiang/");
测试效果:
第一种我们在工厂中直接通过type类型判断,不同的类型生产不同的服装,但是如果type类型过多而且type实现的不一定的Dress服装类,所以放在Manufactor不合适,我们将其实现单独放在一个简单工厂里面。 你会发现,每次不同的类型我们都要去修改简单工厂,牵一发而动,不符合设计模式的"对扩展开放,对修改关闭"的原则,工厂模式可以解决简单工厂无法解决的问题。
工厂模式
假设公司效益比较好,工厂需要新增北京分厂,上海分厂的时候,这是时候通过简单工厂无法解决类扩展的问题,简单工厂之所以简单就是在于在同一个地方进行对象处理,工厂方法模式(Factory Method Pattern)工在基类中建立一个抽象方法,子类可以通过改写这一方法来改变创建对象的具体过程。工厂方法模式让子类来决定如何创建对象,来达到封装的目的。
假设我们新增了北京分厂,属于北京分厂的服装可以直接调用北京工厂来完成:
@implementation BJManufactor -(Dress *)createDress:(NSString *)type{ Dress *dress; if ([type isEqualToString:@"BJ"]) { dress=[[BJDress alloc]init]; }else if([type isEqualToString:@"BJSpecial"]){ dress=[[BJSpecialDress alloc]init]; } return dress; } @end
Manufactor基类中的条件判断:
-(void)startByCondition:(NSString *)type{ Dress *myDress=[self createDress:type]; [myDress provideMaterial]; [myDress product]; }
具体调用实现:
Manufactor *bjfactor=[[BJManufactor alloc]init]; [bjfactor startByCondition:@"BJ"]; NSLog(@"博客园-FlyElephant"); NSLog(@"http://www.cnblogs.com/xiaofeixiang/");
效果:
从对象的创建来讲,这个将对象的创建扩展到了对象子类,从设计原则中中的依赖角度来看,原来的工厂需要依赖的各种具体的服装子类的引用,现在将这些进行各种分类,这里是以工厂的形式进行分类,抽象组件不依赖于具体的实现组件,已经完成的扩展可以不需要变化,如果有新增需求只需要增加新的功能接口,高层组件不需要太大的变化。
抽象工厂模式
抽象工厂模式提供一个接口,用于创建一个对象家族,而无需指定具体类。工厂方法只涉及到创建一个对象的情况,有时我们需要一族对象,上面我针对的对象是工厂,当我们需要工厂提供提供不同的原料,需要的不同的启动资金和人数,才能成立一个真正的工厂,将每个工厂都聚合在一起形成统一的接口,这样我们可以称之为
抽象工厂基类,这里只提供实现了Cloth:
@protocol AbstractFactory <NSObject> @optional -(Cloth *)provideCloth; @end @interface AbstractFactory : NSObject<AbstractFactory> @end
抽象工厂子类BJAbstractFactory:
@implementation BJAbstractFactory -(Cloth *)provideCloth{ return [[Cloth alloc] init]; } @end
Cloth类:
@implementation Cloth -(void)clothMethod{ NSLog(@"Cloth--Cloth"); } @end
Manufactor类中添加两个新的方法:
-(void)configFactory:(AbstractFactory *)factory{ abstractFactory=factory; } -(void)startWithFactory:(NSString *)type{ Dress *myDress=[self createDress:type]; cloth=[abstractFactory provideCloth]; [cloth clothMethod]; [myDress provideMaterial]; [myDress product]; }
方法调用:
Manufactor *factor=[[BJManufactor alloc]init]; [factor configFactory:[[BJAbstractFactory alloc] init]]; [factor startWithFactory:@"BJ"]; NSLog(@"博客园-FlyElephant"); NSLog(@"http://www.cnblogs.com/xiaofeixiang/");
效果:
从实现逻辑来看抽象工厂模式和工厂模式和类似,抽象工厂模式的重点在于创建抽象接口来创建一组相关的产品。抽象工厂模式中,抽象工厂定义接口,所有的具体工厂必须实现该接口,该接口包含一组方法用来生产产品。每个具体工厂能够生产一整组的产品。工程实践中根据实际情况进行择优选择~