iOS学习笔记(5)——设计模式之工厂方法、抽象工厂

工厂方法、抽象工厂都属于对象创建型设计模式,这类设计模式的功能主要是帮我们把对象的创建操作抽取出来。创建对象时我们不需要知道其具体细节,增强了系统的可扩展性。

一、工厂方法

定义:定义创建对象的接口,让子类决定实例化哪一个类,工厂方法使得一个类的实例化延迟到其子类。(《设计模式》(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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值