Objective-C編程之道 iOS設(shè)計模式解析
iOS設(shè)計模式解析-工廠模式
iOS設(shè)計模式解析-抽象工廠模式
iOS設(shè)計模式解析-外觀模式
iOS設(shè)計模式解析-中介者模式
iOS設(shè)計模式解析-觀察者模式
iOS設(shè)計模式解析-裝飾模式
iOS設(shè)計模式解析-責(zé)任鏈模式
iOS設(shè)計模式解析-模板方法
iOS設(shè)計模式解析-策略模式
iOS設(shè)計模式解析-享元模式
iOS設(shè)計模式解析-代碼地址
何為工廠方法模式
工廠方法也稱為虛構(gòu)造器,它適用于這種情況:一個類無法預(yù)期需要生產(chǎn)哪個類的對象,想讓其子類來指定所生成的對象。
工廠方法模式:定義創(chuàng)建對象的接口十气,讓子類決定實例化哪一個類,工廠方法使得一個類的實例化延遲到其子類。
何時使用工廠方法
在以下情形嘁字,自然會考慮使用這一模式夫椭。
- 編譯時無法準(zhǔn)確預(yù)期要創(chuàng)建的對象的類掸掸。
- 類想讓其子類決定在運行時創(chuàng)建什么。
- 類有若干輔助類為其子類蹭秋,而你想將返回哪個子類這一信息局部化扰付。
畫布的實例:
最上層的CanvasView定義了任意CanvasView類型的默認(rèn)行為,其子類用不同圖像在屏幕上展現(xiàn)各種紋理并展現(xiàn)其他可能的特定行為仁讨,PaperCanvasView 與 ClothCanvasView的代碼段如下
PaperCanvasView
#import "CanvasView.h"
@interface PaperCanvasView : CanvasView
@end
#import "PaperCanvasView.h"
@implementation PaperCanvasView
- (id)initWithFrame:(CGRect)frame
{
if(self = [super initWithFrame:frame]){
UIImage *backgroundImage = [UIImage imageNamed:@"paper"];
UIImageView *backgroundView = [[UIImageView alloc]initWithImage:backgroundImage];
[self addSubview:backgroundView];
NSLog(@"paper");
}
return self;
}
@end
注意:@"paper"是紙紋理的圖像的名字羽莺,它被賦給 UIImageView 的實例 backgroundView 然后 backgroundView 作為子視圖添加到主內(nèi)容視圖,以顯示紙的圖像
ClothCanvasView
#import "CanvasView.h"
@interface ClothCanvasView : CanvasView
@end
#import "ClothCanvasView.h"
@implementation ClothCanvasView
- (id)initWithFrame:(CGRect)frame
{
if(self = [super initWithFrame:frame]){
UIImage *backgroundImage = [UIImage imageNamed:@"cloth"];
UIImageView *backgroundView = [[UIImageView alloc]initWithImage:backgroundImage];
[self addSubview:backgroundView];
NSLog(@"cloth");
}
return self;
}
@end
PaperCanvasView 與 ClothCanvasView的實現(xiàn)非常易懂洞豁,它們繼承了CanvasView類中定義的默認(rèn)行為盐固,現(xiàn)在我們定義好了產(chǎn)品,還需要為它們各自定義一個生成器丈挟。
畫布生成器
CanvasViewGenerator
#import <Foundation/Foundation.h>
#import "CanvasView.h"
@interface CanvasViewGenerator : NSObject
- (CanvasView *)canvasViewWithFrame:(CGRect)aFrame;
@end
#import "CanvasViewGenerator.h"
@implementation CanvasViewGenerator
- (CanvasView *)canvasViewWithFrame:(CGRect)aFrame
{
return [[CanvasView alloc]initWithFrame:aFrame];
}
@end
注意:CanvasViewGenerator有一個方法canvasViewWithFrame:(CGRect)aFrame刁卜,這個方法的默認(rèn)實現(xiàn)只是創(chuàng)建并返回?zé)o圖案的CanvasView,這個生成器的子類需要重載這個方法曙咽,返回CanvasView的實際具體類型
PaperCanvasViewGenerator
#import "CanvasViewGenerator.h"
#import "PaperCanvasView.h"
@interface PaperCanvasViewGenerator : CanvasViewGenerator
- (CanvasView *)canvasViewWithFrame:(CGRect)aFrame;
@end
#import "PaperCanvasViewGenerator.h"
@implementation PaperCanvasViewGenerator
- (CanvasView *)canvasViewWithFrame:(CGRect)aFrame
{
return [[PaperCanvasView alloc]initWithFrame:aFrame];
}
@end
PaperCanvasViewGenerator重載canvasViewWithFrame:方法蛔趴,返回PaperCanvasView的實例。
ClothCanvasViewGenerator
#import "CanvasViewGenerator.h"
#import "ClothCanvasView.h"
@interface ClothCanvasViewGenerator : CanvasViewGenerator
- (CanvasView *)canvasViewWithFrame:(CGRect)aFrame;
@end
#import "ClothCanvasViewGenerator.h"
@implementation ClothCanvasViewGenerator
- (CanvasView *)canvasViewWithFrame:(CGRect)aFrame
{
return [[ClothCanvasView alloc]initWithFrame:aFrame];
}
@end
使用畫布
ViewController現(xiàn)在使用原來的CanvasView例朱。為了在運行時加以改變孝情,需要在調(diào)用的時候添加一個方法之拨,通過CanvasViewGenerator取得CanvasView的實例
注意:CanvasViewGenerator defaultGenerator = [[PaperCanvasViewGenerator alloc]init]
此時編譯時defaultGenerator是CanvasViewGenerator類型,運行時的類型由真正初始化的對象(PaperCanvasViewGenerator)*決定
- (void)viewDidLoad {
[super viewDidLoad];
CanvasViewGenerator *defaultGenerator = [[CanvasViewGenerator alloc]init];
[self loadCanvasViewWithGenerator:defaultGenerator];
}
- (void)loadCanvasViewWithGenerator:(CanvasViewGenerator *)generator
{
[self.canvasView removeFromSuperview];//移除
CGRect aFrame = CGRectMake(0, 0, 320, 436);
CanvasView *aCanvasView = [generator canvasViewWithFrame:aFrame];
self.canvasView = aCanvasView;
[self.view addSubview:self.canvasView];
}
因此咧叭,以后用戶選擇特定的畫布類型時蚀乔,應(yīng)用程序會把具體生成器的實例傳給loadCanvasViewWithGenerator:方法,原來的畫布將被新畫布所替換菲茬。
//PaperCanvasViewGenerator生成器
CanvasViewGenerator *defaultGenerator = [[PaperCanvasViewGenerator alloc]init];
//ClothCanvasViewGenerator生成器
CanvasViewGenerator *defaultGenerator = [[ClothCanvasViewGenerator alloc]init];