iOS设计模式(03):工厂方法
2019獨角獸企業重金招聘Python工程師標準>>>
GOF是這樣描述工廠模式的:
“Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.”
?
在基類中定義創建對象的一個接口,讓子類決定實例化哪個類。工廠方法讓一個類的實例化延遲到子類中進行。
?
工廠方法要解決的問題是對象的創建時機,它提供了一種擴展的策略,很好地符合了開放封閉原則。工廠方法也叫做虛構造器(Virtual Constructor)。
?
如下圖所示,是工廠方法的類結構圖:
?
什么時候使用工廠方法?
當是如下情況是,可以使用工廠方法:一個類不知道它所必須創建的對象的類時,一個類希望有它的子類決定所創建的對象時。
?
更多關于工廠方法的介紹,可以參考本文最后給出的參考內容。下面我們就來看看在iOS中工廠方法的一種實現方法。
?
iOS中工廠方法的實現
如下有一個類圖,該圖描述了下面即將實現的工廠方法(利用工廠方法,創建出不同的形狀)。其中BVShapeFactory為工廠方法的基類,BVShape為形狀的基類,BVClient通過BVShapeFactory,利用 BVShapeFactory的子類(BVCircleShapeFactory和BVSquareShapeFactory)分別創建出BVCircleShape和BVSquareShape。
?
如下圖,是在Xcode中創建的相關文件
?
?
(具體實現步驟如下(建議下載本文最后給出的代碼實例,用Xcode查閱代碼):
?
1.創建一個形狀基類BVShape。該類中定義了形狀的基本行為和屬性,如下代碼所示:
?
BVShape.h
1.//
2.// ?BVShape.h
3.// ?FactoryMethodPattern
4.//
5.// ?Created by BeyondVincent on 13-5-15.
6.// ?Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.?
9.#define BV_Exception_Format @"在%@的子類中必須override:%@方法"
10.?
11.@interface BVShape : NSObject
12.?
13.@property (nonatomic, weak)NSString *name;
14.?
15.// 子類必須重寫這個draw方法,否則會拋出異常錯誤
16.-(void)draw;
17.?
18.@end
?
BVShape.m
1.//
2.// ?BVShape.m
3.// ?FactoryMethodPattern
4.//
5.// ?Created by BeyondVincent on 13-5-15.
6.// ?Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.?
9.#import "BVShape.h"
10.?
11.@implementation BVShape
?12.
13.-(id)init
14.{
15. ?self = [super init];
16. ? ?if (self) {
17. ? ? ? ?// 做一些初始化任務
18. ? ?}
19. ? ?return self;
20.}
21.?
22.-(void)draw
23.{
24. ? ?// 如果是通過BVShape的實例調用此處的draw,則繪制一個BVShape圖形
25. ? ?if ([self isMemberOfClass:[BVShape class]]) {
?26. ? ? ? NSLog(@"繪制一個BVShape圖形");
27. ? ?} else {
28. ? ? ? ?// 如果是通過BVShape子類的實例調用了此處的draw,則拋出一個異常:表明子類并沒有重寫draw方法。
29. ? ? ? ?// 注:在OC中并沒有abstract class的概念,只有protocol,如果在基類中只定義接口(沒有具體方法的實現),
30. ? ? ? ?// ? ?則可以使用protocol,這樣會更方便。?
31. ? ? ? ?[NSException raise:NSInternalInconsistencyException
32. ? ? ? ? ? ? ? ? ? ?format:BV_Exception_Format, [NSString stringWithUTF8String:object_getClassName(self)], NSStringFromSelector(_cmd)];
33. ? ?}
34.}
35.?
36.@end
?
?
在上面的代碼中定義了一個draw方法,為了讓子類必須實現該方法,在BVShape中做了特殊處理,具體內容可以看上面的代碼,已經有注視了。
?
2.子類化形狀基類。首先子類化一個圓形類:BVCircleShape。
BVCircleShape.h
1.//
2.// ?BVCircleShape.h
3.// ?FactoryMethodPattern
4.//
5.// ?Created by BeyondVincent on 13-5-15.
6.// ?Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.?
9.#import "BVShape.h"
10.?
11.@interface BVCircleShape : BVShape
12.?
13.@end
?
BVCircleShape.m
1.//
2.// ?BVCircleShape.m
3.// ?FactoryMethodPattern
4.//
5.// ?Created by BeyondVincent on 13-5-15.
6.// ?Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.?
9.#import "BVCircleShape.h"
?10.
11.@implementation BVCircleShape
12.?
13.-(void)draw
14.{
15. ? ?NSLog(@"繪制一個BVCircleShape圖形");
16.}
17.?
18.@end
?
?
在上面的子類中,重寫了基類的draw方法。同樣,我們再子類化一個正方形類,并重寫draw方法,如下代碼所示:
BVSquareShape.h
1.//
2.// ?BVSquareShape.h
3.// ?FactoryMethodPattern
4.//
5.// ?Created by BeyondVincent on 13-5-15.
6.// ?Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.?
9.#import "BVShape.h"
10.?
11.@interface BVSquareShape : BVShape
?12.
13.@end
?
BVSquareShape.m
1.//
2.// ?BVSquareShape.m
3.// ?FactoryMethodPattern
4.//
5.// ?Created by BeyondVincent on 13-5-15.
6.// ?Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.?
9.#import "BVSquareShape.h"
10.
11.@implementation BVSquareShape
12.?
13.-(void)draw
14.{
15. ? ?NSLog(@"繪制一個BVSquareShape圖形");
16.}
17.?
18.@end
?
3.創建一個工廠方法的基類BVShapeFactory
BVShapeFactory.h
1.//
2.// ?BVShapeFactory.h
3.// ?FactoryMethodPattern
4.//
5.// ?Created by BeyondVincent on 13-5-15.
6.// ?Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.?
9.#import "BVShape.h"
10.?
11.@interface BVShapeFactory : NSObject
12.?
13.-(BVShape *) factoryMethod;
14.?
15.@end
?
BVShapeFactory.m
1.//
2.// ?BVShapeFactory.m
3.// ?FactoryMethodPattern
4.//
5.// ?Created by BeyondVincent on 13-5-15.
6.// ?Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.?
9.#import "BVShapeFactory.h"
10.?
11.@implementation BVShapeFactory
12.?
13.-(BVShape *)factoryMethod
14.{
15. ? ?// 在此處,子類必須重寫factoryMethod方法。當然,在工廠模式中,也可以在此處返回一個默認的Product。
16. ? ?// 如果是通過BVShapeFactory子類的實例調用了此處的factoryMethod,則拋出一個異常:表明子類并沒有重寫factoryMethod方法。
17. ? ?[NSException raise:NSInternalInconsistencyException
18. ? ? ? ? ? ? ? ?format:BV_Exception_Format, [NSString stringWithUTF8String:object_getClassName(self)], NSStringFromSelector(_cmd)];
19.?
20. ? ?// 下面這個return語句只是為了消除警告,實際上永遠都不會執行到這里。
21. ? ?return nil;
22.}
23.?
24.@end
?
在上面的代碼中,定義了一個factoryMethod,該類的子類必須實現該方法,通過實現該方法,返回一個具體的形狀對象。下面來看看該類的子類化。
?
4.子類化工廠方法的基類。首先子類化一個圓形工廠方法BVCircleShapeFactory:
BVCircleShapeFactory.h
1.//
2.// ?BVCircleShapeFactory.h
3.// ?FactoryMethodPattern
4.//
5.// ?Created by BeyondVincent on 13-5-15.
6.// ?Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
?8.
9.#import "BVShapeFactory.h"
10.#import "BVCircleShape.h"
11.?
12.@interface BVCircleShapeFactory : BVShapeFactory
13.?
14.@end
?
BVCircleShapeFactory.m
1.//
2.// ?BVCircleShapeFactory.m
3.// ?FactoryMethodPattern
4.//
5.// ?Created by BeyondVincent on 13-5-15.
6.// ?Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.?
9.#import "BVCircleShapeFactory.h"
?10.
11.@implementation BVCircleShapeFactory
12.?
13.-(BVShape *)factoryMethod
14.{
15. ? ?return [[BVCircleShape alloc] init];
16.}
17.?
18.@end
?
如上代碼所示,重寫了factoryMethod,返回一個BVCircleShape實例。下面來看看另外一個子類BVSquareShapeFactory:
BVSquareShapeFactory.h
1.//
2.// ?BVSquareShapeFactory.h
3.// ?FactoryMethodPattern
4.//
5.// ?Created by BeyondVincent on 13-5-15.
6.// ?Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.?
9.#import "BVShapeFactory.h"
10.#import "BVSquareShape.h"
11.?
12.@interface BVSquareShapeFactory : BVShapeFactory
13.?
14.@end
?
BVSquareShapeFactory.m
1.//
2.// ?BVSquareShapeFactory.m
3.// ?FactoryMethodPattern
4.//
5.// ?Created by BeyondVincent on 13-5-15.
6.// ?Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.?
9.#import "BVSquareShapeFactory.h"
10.?
11.@implementation BVSquareShapeFactory
12.?
13.-(BVShape *)factoryMethod
14.{
15. ? ?return [[BVSquareShape alloc] init];
16.}
17.?
18.@end
?
該子類返回的是一個BVSquareShape實例。
?
5.工廠方法的使用。定義一個BVClient類,在該類中演示工廠方法的使用。代碼如下:
BVClient.h
1.//
2.// ?BVClient.h
3.// ?FactoryMethodPattern
4.//
5.// ?Created by BeyondVincent on 13-5-15.
6.// ?Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.?
9.@interface BVClient : NSObject
?10.
11.-(void)doSomething;
12.?
13.@end
?
BVClient.m
1.//
2.// ?BVClient.m
3.// ?FactoryMethodPattern
4.//
5.// ?Created by BeyondVincent on 13-5-15.
6.// ?Copyright (c) 2013年 BeyondVincent. All rights reserved.
7.//
8.?
9.#import "BVClient.h"
10.?
11.#import "BVShapeFactory.h"
12.#import "BVCircleShapeFactory.h"
13.#import "BVSquareShapeFactory.h"
14.?
15.#import "BVShape.h"
16.#import "BVCircleShape.h"
17.#import "BVSquareShape.h"
18.?
19.@implementation BVClient
?20.
21.-(void)doSomething
22.{
23. ? ?// 工廠方法的實例化
24. ? ?BVShapeFactory *circleShapefactory = [[BVCircleShapeFactory alloc] init];
25. ? ?BVShapeFactory *squareShapefactory = [[BVSquareShapeFactory alloc] init];
26.?
27. ? ?// 通過工廠方法實例化對應的形狀
28. ? ?BVShape *circleShape = [circleShapefactory factoryMethod];
29. ? ?BVShape *squareShape = [squareShapefactory factoryMethod];
30.?
31. ? ?// 調用形狀的方法
32. ? ?[circleShape draw];
33. ? ?[squareShape draw];
34.}
35.?
36.@end
?
如上代碼所示,首先實例化兩個工廠方法,并通過工廠方法創建出對應的形狀,最后調用形狀的draw方法進行測試。會在控制臺窗口輸出如下內容:
2013-05-16 10:12:46.292 FactoryMethodPattern[2845:c07] 繪制一個BVCircleShape圖形
2013-05-16 10:12:46.295 FactoryMethodPattern[2845:c07] 繪制一個BVSquareShape圖形
轉載于:https://my.oschina.net/u/1432769/blog/375410
總結
以上是生活随笔為你收集整理的iOS设计模式(03):工厂方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android-RelativeLayo
- 下一篇: 架设HmailServer邮件服务器以及