Objective-C編程之道 iOS設(shè)計(jì)模式解析
iOS設(shè)計(jì)模式解析-工廠模式
iOS設(shè)計(jì)模式解析-抽象工廠模式
iOS設(shè)計(jì)模式解析-外觀模式
iOS設(shè)計(jì)模式解析-中介者模式
iOS設(shè)計(jì)模式解析-觀察者模式
iOS設(shè)計(jì)模式解析-裝飾模式
iOS設(shè)計(jì)模式解析-責(zé)任鏈模式
iOS設(shè)計(jì)模式解析-模板方法
iOS設(shè)計(jì)模式解析-策略模式
iOS設(shè)計(jì)模式解析-享元模式
iOS設(shè)計(jì)模式解析-代碼地址
抽象工廠
抽象工廠:定義一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無需指定他們具體的類谱净。
抽象工廠和工廠的比較
抽象工廠
- 通過對象組合創(chuàng)建抽象產(chǎn)品
- 創(chuàng)建多系列產(chǎn)品
- 必須修改父類的接口才能支持新的產(chǎn)品
工廠方法
- 通過類繼承創(chuàng)建抽象產(chǎn)品
- 創(chuàng)建一種產(chǎn)品
- 子類話創(chuàng)建者并重載工廠方法以創(chuàng)建新產(chǎn)品
軟件設(shè)計(jì)的黃金法則:變動(dòng)需要抽象衩匣。
如果有多個(gè)類共有相同的行為,但實(shí)際實(shí)現(xiàn)不同,則可能需要某種抽象類型作為其父類被繼承洁闰。
產(chǎn)品由兩個(gè)不同的品牌工廠AcmeBrandingFactory和SierraBrandingFactory來“生產(chǎn)”,他們各自重載抽象BrandingFactory類中定義的工廠方法brandedView洋只、brandedMainButton划乖、brandedToolbar贬养,并根據(jù)工廠設(shè)計(jì)所針對的品牌返回具體產(chǎn)品。
超類的類方法factory是返回具體BrandingFactory的正確版本的工廠方法琴庵、其子類不應(yīng)重載這個(gè)方法(盡管子類能夠這么做)误算,factory方法根據(jù)當(dāng)前的編譯配置返回一個(gè)具體品牌工廠的實(shí)例(個(gè)人理解:可以根據(jù)條件不同返回一個(gè)具體品牌工廠的實(shí)例)
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類方法中,使用預(yù)處理器定義告訴編譯器讓這個(gè)方法返回哪個(gè)具體工廠迷殿。如果定義了宏USE_ACME儿礼,那么運(yùn)行時(shí)會(huì)使用語句
return [[[AcmeBrandingFactory alloc] init] autorelease];
如果定義了宏USE_SIERRA,那么運(yùn)行時(shí)會(huì)使用語句
return [[[SierraBrandingFactory alloc] init] autorelease];
此外的其他情況贪庙,此方法會(huì)返回nil
AcmeBrandingFactory
#import <Foundation/Foundation.h>
#import "BrandingFactory.h"
@interface AcmeBrandingFactory : BrandingFactory
- (UIView *) brandedView;
- (UIButton *) brandedMainButton;
- (UIToolbar *) brandedToolbar;
@end
AcmeBrandingFactory繼承基類BrandingFactory蜘犁,并重載其工廠方法為此品牌生產(chǎn)正確的UI元素,原始的factory類方法沒有被重載止邮,因?yàn)樗居糜诟割悇?chuàng)建具體BrandingFactory的實(shí)例这橙,但是我們無法防止類方法被子類重載。
#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
每個(gè)工廠方法的實(shí)現(xiàn)返回反映實(shí)際品牌的Acme*產(chǎn)品的實(shí)例导披。
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
說明:當(dāng)現(xiàn)有的抽象工廠需要支持新產(chǎn)品時(shí)屈扎,需要向父類添加相應(yīng)的新工廠方法。這意味著也要修改其子類以支持新產(chǎn)品的新工廠方法
調(diào)用
- (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];
此時(shí)調(diào)用只有這一句話撩匕,在這里要深入理解抽象工廠的定義:提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對象的接口鹰晨,無需指定它們具體的類