iOS設計模式之(五)生成器模式(建造模式)
本文首發於個人部落格
前言
什麼是生成器模式
生成器模式 又名:建造模式 屬於建立型模式,在wikipedia中的定義如下
生成器模式(英:Builder Pattern)是一種設計模式,又名:建造模式,是一種物件構建模式。它可以將複雜物件的建造過程抽象出來(抽象類別),使這個抽象過程的不同實現方法可以構造出不同表現(屬性)的物件。
適用性
在以下情況使用生成器模式:
- 當建立複雜物件的演算法應該獨立於該物件的組成部分以及它們的裝配方式時;
- 當構造過程必須允許被構造的物件有不同的表示時。
參與者
- Builder 抽象建造者類
- 為建立一個Product物件的各個部件指定抽象介面。
- ConcreteBuilder 建造者類
- 實現Builder的介面以構造和裝配該產品的各個部件。
- 定義並明確它所建立的表示。
- 提供一個檢索產品的介面
- Director 導演類
- 構造一個使用Builder介面的物件。
- Product 產品類
- 表示被構造的複雜物件。ConcreateBuilder建立該產品的內部表示並定義它的裝配過程。
- 包含定義組成部件的類,包括將這些部件裝配成最終產品的介面。
程式碼
YZBuilderCar
建立YZBuilderCar
類,有兩個屬性,分別是名字和價格
#import <Foundation/Foundation.h>
@interface YZBuilderCar : NSObject
@property (nonatomic,strong)NSString *name;// 名字
@property (nonatomic,strong)NSString *price;// 價格
-(YZBuilderCar *)makeCar;
@end
複製程式碼
實現如下
#import "YZBuilderCar.h"
@interface YZBuilderCar()
@end
@implementation YZBuilderCar
- (NSString *)description{
return [NSString stringWithFormat:@"我是一輛:%@ 車 價格:%@",self.name,self.price];
}
- (YZProductCar *)makeCar{
YZBuilderCar *car = [[YZBuilderCar alloc] init];
car.name = self.name;
car.price = self.price;
return car;
}
@end
複製程式碼
YZBMWCar
和YZAudiCar
繼承自YZBuilderCar
建立車型YZBMWCar
#import "YZProductCar.h"
@interface YZBMWCar : YZBuilderCar
@end
#import "YZBMWCar.h"
@implementation YZBMWCar
- (instancetype)init
{
self = [super init];
if (self) {
self.name = @"寶馬740Li";
self.price = @"98萬";
}
return self;
}
@end
複製程式碼
建立車型YZAudiCar
#import "YZProductCar.h"
@interface YZAudiCar : YZBuilderCar
@end
#import "YZAudiCar.h"
@implementation YZAudiCar
- (instancetype)init
{
self = [super init];
if (self) {
self.name = @"奧迪Q5";
self.price = @"45萬";
}
return self;
}
@end
複製程式碼
YZDirector
#import <Foundation/Foundation.h>
#import "YZBuilderCar.h"
@interface YZDirector : NSObject
// 建造一輛車
+ (YZProductCar *)creatBuickCar:(YZBuilderCar *)builder;
@end
#import "YZDirector.h"
@implementation YZDirector
+ (YZProductCar *)creatBuickCar:(YZBuilderCar *)builder{
YZProductCar *car = [builder makeCar];
return car;
}
@end
複製程式碼
使用
int main(int argc,const char * argv[]) {
@autoreleasepool {
YZBuilderCar *car = [[YZBMWCar alloc] init];
YZDirector *dir = [YZDirector creatBuickCar:car];
NSLog(@"%@",dir.description);
}
return 0;
}
複製程式碼
輸出為
我是一輛:寶馬740Li 車 價格:98萬
建造者模式的優點
首先,建造者模式的封裝性很好。使用建造者模式可以有效的封裝變化,在使用建造者模式的場景中,一般產品類和建造者類是比較穩定的,因此,將主要的業務邏輯封裝在Director類中對整體而言可以取得比較好的穩定性。
其次,建造者模式很容易進行擴充套件。如果有新的需求,通過實現一個新的ConcreteBuilder類就可以完成,基本上不用修改之前已經測試通過的程式碼,因此也就不會對原有功能引入風險。
建造者模式與工廠模式的區別
我們可以看到,建造者模式與工廠模式是極為相似的,總體上,建造者模式僅僅只比工廠模式多了一個"導演類"的角色。在建造者模式的類圖中,假如把這個導演類看做是最終呼叫的客戶端,那麼圖中剩餘的部分就可以看作是一個簡單的工廠模式了。
與工廠模式相比,建造者模式一般用來建立更為複雜的物件,因為物件的建立過程更為複雜,因此將物件的建立過程獨立出來組成一個新的類——導演類。也就是說,工廠模式是將物件的全部建立過程封裝在工廠類中,由工廠類向客戶端提供最終的產品;而建造者模式中,建造者類一般只提供產品類中各個元件的建造,而將具體建造過程交付給導演類。由導演類負責將各個元件按照特定的規則組建為產品,然後將組建好的產品交付給客戶端。
總結
建造者模式與工廠模式類似,他們都是建造者模式,適用的場景也很相似。一般來說,如果產品的建造很複雜,那麼請用工廠模式;如果產品的建造更復雜,那麼請用建造者模式。