Objective-C编程之道 iOS设计模式解析
iOS设计模式解析-工厂模式
iOS设计模式解析-抽象工厂模式
iOS设计模式解析-外观模式
iOS设计模式解析-中介者模式
iOS设计模式解析-观察者模式
iOS设计模式解析-装饰模式
iOS设计模式解析-责任链模式
iOS设计模式解析-模板方法
iOS设计模式解析-策略模式
iOS设计模式解析-享元模式
iOS设计模式解析-代码地址
抽象工厂
抽象工厂:定义一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
抽象工厂和工厂的比较
抽象工厂
- 通过对象组合创建抽象产品
- 创建多系列产品
- 必须修改父类的接口才能支持新的产品
工厂方法
- 通过类继承创建抽象产品
- 创建一种产品
- 子类话创建者并重载工厂方法以创建新产品
软件设计的黄金法则:变动需要抽象。
如果有多个类共有相同的行为,但实际实现不同,则可能需要某种抽象类型作为其父类被继承。
产品由两个不同的品牌工厂AcmeBrandingFactory和SierraBrandingFactory来“生产”,他们各自重载抽象BrandingFactory类中定义的工厂方法brandedView、brandedMainButton、brandedToolbar,并根据工厂设计所针对的品牌返回具体产品。
超类的类方法factory是返回具体BrandingFactory的正确版本的工厂方法、其子类不应重载这个方法(尽管子类能够这么做),factory方法根据当前的编译配置返回一个具体品牌工厂的实例(个人理解:可以根据条件不同返回一个具体品牌工厂的实例)
BrandingFactory
#import <Foundation/Foundation.h>
#import<UIKit/UIKit.h>
@interface BrandingFactory : NSObject
+ (BrandingFactory *) factory;
- (UIView *) brandedView;
- (UIButton *) brandedMainButton;
- (UIToolbar *) brandedToolbar;
@end
#import "BrandingFactory.h"
#import "AcmeBrandingFactory.h"
#import "SierraBrandingFactory.h"
@implementation BrandingFactory
+ (BrandingFactory *) factory
{
#if defined (USE_ACME)
return [[[AcmeBrandingFactory alloc] init] autorelease];
#elif defined (USE_SIERRA)
return [[[SierraBrandingFactory alloc] init] autorelease];
#else
return nil;
#endif
}
- (UIView *) brandedView
{
return nil;
}
- (UIButton *) brandedMainButton
{
return nil;
}
- (UIToolbar *) brandedToolbar
{
return nil;
}
@end
factory类方法中,使用预处理器定义告诉编译器让这个方法返回哪个具体工厂。如果定义了宏USE_ACME,那么运行时会使用语句
return [[[AcmeBrandingFactory alloc] init] autorelease];
如果定义了宏USE_SIERRA,那么运行时会使用语句
return [[[SierraBrandingFactory alloc] init] autorelease];
此外的其他情况,此方法会返回nil
AcmeBrandingFactory
#import <Foundation/Foundation.h>
#import "BrandingFactory.h"
@interface AcmeBrandingFactory : BrandingFactory
- (UIView *) brandedView;
- (UIButton *) brandedMainButton;
- (UIToolbar *) brandedToolbar;
@end
AcmeBrandingFactory继承基类BrandingFactory,并重载其工厂方法为此品牌生产正确的UI元素,原始的factory类方法没有被重载,因为它原本用于父类创建具体BrandingFactory的实例,但是我们无法防止类方法被子类重载。
#import "AcmeBrandingFactory.h"
#import "AcmeView.h"
#import "AcmeMainButton.h"
#import "AcmeToolbar.h"
@implementation AcmeBrandingFactory
- (UIView *) brandedView
{
// returns a custom view for Acme
return [[AcmeView alloc] init];
}
- (UIButton *) brandedMainButton
{
// returns a custom main button for Acme
return [[AcmeMainButton alloc] init];
}
- (UIToolbar *) brandedToolbar
{
// returns a custom toolbar for Acme
return [[AcmeToolbar alloc] init];
}
@end
每个工厂方法的实现返回反映实际品牌的Acme*产品的实例。
SierraBrandingFactory
#import <Foundation/Foundation.h>
#import "BrandingFactory.h"
@interface SierraBrandingFactory : BrandingFactory
- (UIView*) brandedView;
- (UIButton*) brandedMainButton;
- (UIToolbar*) brandedToolbar;
@end
#import "SierraBrandingFactory.h"
#import "SierraView.h"
#import "SierraMainButton.h"
#import "SierraToolbar.h"
@implementation SierraBrandingFactory
- (UIView*) brandedView
{
// returns a custom view for Sierra
return [[SierraView alloc] init];
}
- (UIButton*) brandedMainButton
{
// returns a custom main button for Sierra
return [[SierraMainButton alloc] init];
}
- (UIToolbar*) brandedToolbar
{
// returns a custom toolbar for Sierra
return [[SierraToolbar alloc] init];
}
@end
说明:当现有的抽象工厂需要支持新产品时,需要向父类添加相应的新工厂方法。这意味着也要修改其子类以支持新产品的新工厂方法
调用
- (void)viewDidLoad {
[super viewDidLoad];
BrandingFactory * factory = [BrandingFactory factory];
//...
UIView * view = [factory brandedView];
//... put the view on a proper location in view
//...
UIButton * button = [factory brandedMainButton];
//... put the button on a proper location in view
//...
UIToolbar * toolbar = [factory brandedToolbar];
}
注意:BrandingFactory * factory = [BrandingFactory factory];
此时调用只有这一句话,在这里要深入理解抽象工厂的定义:提供一个创建一系列相关或相互依赖对象的接口,无需指定它们具体的类
网友评论