工厂方法、抽象工厂都属于对象创建型设计模式,这类设计模式的功能主要是帮我们把对象的创建操作抽取出来。创建对象时我们不需要知道其具体细节,增强了系统的可扩展性。
一、工厂方法
定义:定义创建对象的接口,让子类决定实例化哪一个类,工厂方法使得一个类的实例化延迟到其子类。(《设计模式》(Addison-Wesley, 1994))
该设计模式也被称为虚构造器(Virtual Constructor)。工厂方法针对每一种“产品”均提供一个工厂类,由相应的工厂示例创建相应的“产品”。简单来讲就是,有多个派生于同一父类的具体工厂类,每个具体工厂类只生产一种具体的产品类,而且这些产品类均派生于同一个父类。其静态类图如下所示:
代码示例:
Car.h
#import <UIKit/UIKit.h>
@interface Car : NSObject
{
// 一些私有变量
}
// 一些公有属性
@property(strong, nonatomic) Engine *engine;
@property(strong, nonatomic) Wheel *wheel;
@property(copy, nonatomic) NSString *brand;
// 一些其他的特定行为
-(void)addEngine;
-(void)addWheel;
@end
Car.m
#import "Car.h"
@implementation Car
-(id)initCarWithBrand:(NSString *)brand
{
// 一些初始化操作
_brand = brand;
return self;
}
-(void)addBrand
{
// 添加商标
}
-(void)addEngine:(Engine *)engine
{
// 添加引擎
}
-(void)addWheel:(Wheel *)wheel
{
// 添加车轮
}
@end
BentleyCar.h
#import "Car.h"
@interface BentleyCar : Car
{
// 一些私有变量
}
@end
BentleyCar.m
#import "BentleyCar.h"
@implementation BentleyCar
-(id)initCarWithBrand:(NSString *)brand
{
if(self = [super initCarWithBrand:brand])
{
engine = [[BentleyEngine alloc] init];
wheel = [[BentleyWheel alloc] init];
[self addEngine:engine];
[self addWheel:wheel];
[self addBrand];
}
return self
}
@end
LamborghiniCar.h
#import "Car.h"
@interface LamborghiniCar : Car
{
// 一些私有变量
}
@end
LamborghiniCar.m
#import "BentleyCar.h"
@implementation LamborghiniCar
-(id)initCarWithBrand:(NSString *)brand
{
if(self = [super initCarWithBrand:brand])
{
engine = [[LamborghiniEngine alloc] init];
wheel = [[LamborghiniWheel alloc] init];
[self addEngine:engine];
[self addWheel:wheel];
[self addBrand];
}
return self
}
@end
CarFactory.h
#import "Car.h"
@interface CarFactory : NSObject
{
}
-(Car *) createCarWithBrand:(NSString *)brand;
@end
CarFactory.m
#import "CarFactory.h"
@implementation CarFactory
-(Car *) createCarWithBrand:(NSString *)brand
{
return [[[Car alloc]initCarWithBrand:brand] autorelease];
}
@end
BentleyCarFactory.h
#import "CarFactory.h"
@interface BentleyCarFactory : CarFactory
{
}
-(Car *) createCar;
-(Car *) createCarWithBrand:(NSString *)brand;
@end<strong>
</strong>
BentleyCarFactory.m
#import "BentleyCar.h"
@implementation BentleyCarFactory
-(Car *) createCar
{
return [self createCarWithBrand:@"Bentley"];
}
-(Car *) createCarWithBrand:(NSString *)brand
{
return [[[BentleyCar alloc]initCarWithBrand:brand] autorelease];
}
@end
LamborghiniCarFactory.h
#import "CarFactory.h"
@interface LamborghiniCarFactory : CarFactory
{
}
-(Car *) createCar;
-(Car *) createCarWithBrand:(NSString *)brand;
@end
LamborghiniCarFactory.m
#import "LamborghiniCar.h"
@implementation LamborghiniCarFactory
-(Car *) createCar
{
return [self createCarWithBrand:@"Lamborghini"];
}
-(Car *) createCarWithBrand:(NSString *)brand
{
return [[[LamborghiniCar alloc]initCarWithBrand:brand] autorelease];
}
@end
CarClientController.h
#import "Car.h"
#import "CarFactory.h"
#import "BentleyCarFactory.h"
#import "LamborghiniCarFactory.h"
@interface CarClientController : UIViewController
{
@private
Car *car;
}
@property (retain, nonatomic) Car *car;
-(Car *) createCarWithFactory:(CarFactory *)factory;
@end
CarClientController.m
#import "CarClientController.h"
@implementation CarClientController
{
Car *bentleyCar;
}
-(void)viewDidLoad
{
[super viewDidLoad];
// 创建Bentley生产工厂
CarFactory *carFactory = [[[BentleyCarFactory alloc] init] autorelease];
bentleyCar = [self createCarWithFactory:carFactory];
}
-(Car *) createCarWithFactory:(CarFactory *)factory;
{
Car *aCar = [factory createCarWithBrand:brand];
return aCar;
}
@end
CocoaTouch框架中的工厂方法:
工厂方法在CocoaTouch框架中随处可见,我们所熟知的两步对象创建法:[[XXXClass alloc]init]。除此之外,还有一些比较便利的方法可以返回类的实例,例如:NSNumber有很多numberWithXXX的方法,其中有两个类方法:
numberWithBool;
numberWithChar;
我们向NSNumber发送[NSNumber numberWithBool:bool]和[NSNumber numberWithChar:char]以获得与传入参数相同类型的NSNumber实例。与如何创建NSNumber具体子类型实例有关的所有细节,都由NSNumber的类工厂方法负责。
定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
抽象工厂是工厂方法模式的升级,其通用类图如下所示:
在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种很好的解决方式。
假设:BMW和Benze都有两条产品线生产SUV和CRV型汽车,首先,看一下该产品族的类图。
创建抽象工厂。
AbstractFactory.h
#import <UIKit/UIKit.h>
@interface AbstractFactory : NSObject
{
}
// 类方法
+(AbstractFactory *)factory;
// 生产SUV
-(SUVCar *)createSUV;
// 生产CRV
-(CRVCar *)createCRV;
@end<strong>
</strong>
AbstractFactory.m
#import "AbstractFactory.h"
#import "BMWFactory.h"
#import "BenzeFactory.h"
@implementation AbstractFactory
+(AbstractFactory *)factory
{
#if defined (BMW_Factory)
return [[[BMWFactory alloc] init] autorelease];
#else if defined (Benze_Factory)
return [[[BenzeFactory alloc] init] autorelease];
#else
return nil;
#endif
}
-(SUVCar *)createSUV;
{
return nil;
}
-(CRVCar *)createCRV;
{
return nil;
}
@end
创建两个继承于抽象工厂的具体工厂子类,分别生产各自品牌的不同型号的汽车
BMWFactory.h
#import "AbstractFactory.h"
@interface BMWFactory : AbstractFactory
{
}
-(SUVCar *)createSUV;
-(CRVCar *)createCRV;
@end
BMWFactory.m
#import "BMWFactory.h"
@implementation BMWFactory
-(SUVCar *)createSUV
{
return [[[SUVBMW alloc] init] autorelease];
}
-(CRVCar *)createSUV
{
return [[[CRVBMW alloc] init] autorelease];
}
@end
BenzeFactory.h
#import "AbstractFactory.h"
@interface BenzeFactory : AbstractFactory
{
}
-(SUVCar *)createSUV;
-(CRVCar *)createCRV;
@end
BenzeFactory.m
#import "BenzeFactory.h"
@implementation BenzeFactory
-(SUVCar *)createSUV
{
return [[[SUVBenze alloc] init] autorelease];
}
-(CRVCar *)createSUV
{
return [[[CRVBenze alloc] init] autorelease];
}
@end
CarClient.h
#import "AbstractFactory"
#import "AbstractSUV"
#import "AbstractCRV"
@interface CarClient : UIViewController
@end
CarClient.m
#import "CarClient.h"
#define (Benze_Factory)
@implementation CarClient
-(void)viewDidLoad
{
AbstractFactory *factory = [AbstractFactory factory];
SUVCar *suv = [factory createSUV];
CRVCar *crv = [factory createCRV];
}
@end