本篇文章将介绍iOS开发中设计模式的另外一种:工厂模式。工厂方法要解决的问题是对象的创建时机,它提供了一种扩展的策略,很好地符合了开放封闭原则。工厂方法也叫做虚构造器(Virtual Constructor)。
工厂模式:在基类中定义创建对象的一个接口,让子类决定实例化哪个类。工厂方法让一个类的实例化延迟到子类中进行。
它适用于当一个类无法预期需要生成哪个类的对象时,想让其子类来指定所生成的对象。
通过下面例子简单了解工厂模式的设计:例如,有一家生产汽车的工厂,汽车有两种品牌,一个奥迪,一个别克。经销商进什么类型的原件一定要告诉工厂,工厂再按照原件生产特定品牌的汽车。后来这家工厂有钱了,开了两家工厂,一家生产奥迪汽车,一家生产别克汽车。这样经销商直接将货进到对应的工厂,工厂直接生产对应的汽车。
HXCar.h
#import <Foundation/Foundation.h>
@interface HXCar : NSObject
/**
* 是车都会跑
*/
- (void)run;
@end
HXCar.m
#import "HXCar.h"
@implementation HXCar
- (void)run {
NSLog(@"车会跑");
}
@end
现有两种品牌的汽车(继承HXCar):
HXAodiCar.h
#import "HXCar.h"
@interface HXAodiCar : HXCar
@end
HXAodiCar.m
#import "HXAodiCar.h"
@implementation HXAodiCar
- (void)run {
NSLog(@"奥迪车------会跑");
}
@end
HXBiekeCar.h
#import "HXCar.h"
@interface HXBiekeCar : HXCar
@end
HXBiekeCar.m
#import "HXBiekeCar.h"
@implementation HXBiekeCar
- (void)run {
NSLog(@"别克车------会跑");
}
@end
有一家工厂生产这两种品牌的汽车,只能根据不同的原件生产不同品牌的汽车。
HXCarFactory.h
#import <Foundation/Foundation.h>
typedef enum {
HXCarFactoryAodi,
HXCarFactoryBieke
} HXFactoryType;
@class HXCar;
@interface HXCarFactory : NSObject
/**
* 工厂可以生产两种品牌的车,根据汽车原件生产相应的汽车
*/
- (HXCar *)productCar:(HXFactoryType)type;
- (HXCar *)productCar;
@end
HXCarFactory.m
#import "HXCarFactory.h"
#import "HXAodiCar.h"
#import "HXBiekeCar.h"
@implementation HXCarFactory
/**
* 工厂可以生产两种品牌的车,根据汽车原件生产相应的汽车
*/
- (HXCar *)productCar:(HXFactoryType)type {
HXCar *car = nil;
switch (type) {
case HXCarFactoryAodi:
car = [[HXAodiCar alloc] init];
break;
case HXCarFactoryBieke:
car = [[HXBiekeCar alloc] init];
break;
default:
break;
}
return car;
}
- (HXCar *)productCar {
return nil;
}
@end
后来这家工厂开了两家工厂,一家生产奥迪,一家生产别克(继承HXCarFactory):
HXAodiCarFactory.h
#import "HXCarFactory.h"
@interface HXAodiCarFactory : HXCarFactory
@end
HXAodiCarFactory.m
#import "HXAodiCarFactory.h"
#import "HXAodiCar.h"
@implementation HXAodiCarFactory
- (HXCar *)productCar {
return [[HXAodiCar alloc] init];
}
@end
HXBiekeCarFactory.h
#import "HXCarFactory.h"
@interface HXBiekeCarFactory : HXCarFactory
@end
HXBiekeCarFactory.m
#import "HXBiekeCarFactory.h"
#import "HXBiekeCar.h"
@implementation HXBiekeCarFactory
- (HXCar *)productCar {
return [[HXBiekeCar alloc] init];
}
@end
main.m中例子如下:
int main(int argc, char * argv[]) {
@autoreleasepool {
// 汽车工厂
HXCarFactory *carFactory = [[HXCarFactory alloc] init];
// 汽车工厂根据汽车原件生产出一辆汽车
HXCar *car = [carFactory productCar:HXCarFactoryAodi];
[car run];
car = [carFactory productCar:HXCarFactoryBieke];
[car run];
// 生产奥迪车的工厂
HXAodiCarFactory *aodiFactory = [[HXAodiCarFactory alloc] init];
// 该工厂直接生成出来汽车,就是奥迪汽车
HXCar *car1 = [aodiFactory productCar];
[car1 run];
// 生成别克车的工厂
HXBiekeCarFactory *biekeFactory = [[HXBiekeCarFactory alloc] init];
// 则该工厂生产出来的汽车,就是别克汽车
HXCar *car2 = [biekeFactory productCar];
[car2 run];
}
}
运行结果:
工厂模式的优点:
工厂模式的核心是工厂类,该类中含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅负责“消费”产品。工厂模式实现了对责任的分割。
缺点:
模式中工厂类集中了所有的产品创建逻辑,形成一个无所不知的全能类,当所有的类不是继承自同一个父类的时候扩展比较困难。