使用多個簡單的對象一步一步構(gòu)建成一個復(fù)雜的對象。這種類型的設(shè)計模式屬于創(chuàng)建型模式蓬网,它提供了一種創(chuàng)建對象的最佳方式窒所。
一個 Builder 類會一步一步構(gòu)造最終的對象。該 Builder 類是獨立于其他對象的帆锋。
介紹
意圖:將一個復(fù)雜的構(gòu)建與其表示相分離吵取,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。
主要解決:主要解決在軟件系統(tǒng)中锯厢,有時候面臨著"一個復(fù)雜對象"的創(chuàng)建工作皮官,其通常由各個部分的子對象用一定的算法構(gòu)成;由于需求的變化实辑,這個復(fù)雜對象的各個部分經(jīng)常面臨著劇烈的變化捺氢,但是將它們組合在一起的算法卻相對穩(wěn)定。
何時使用:一些基本部件不會變剪撬,而其組合經(jīng)常變化的時候摄乒。
如何解決:將變與不變分離開。
關(guān)鍵代碼:建造者:創(chuàng)建和提供實例残黑,導(dǎo)演:管理建造出來的實例的依賴關(guān)系馍佑。
應(yīng)用實例: 1、去肯德基梨水,漢堡拭荤、可樂、薯條疫诽、炸雞翅等是不變的舅世,而其組合是經(jīng)常變化的,生成出所謂的"套餐"奇徒。
優(yōu)點: 1歇终、建造者獨立,易擴(kuò)展逼龟。 2评凝、便于控制細(xì)節(jié)風(fēng)險。
缺點: 1腺律、產(chǎn)品必須有共同點奕短,范圍有限制。 2匀钧、如內(nèi)部變化復(fù)雜翎碑,會有很多的建造類。
使用場景: 1之斯、需要生成的對象具有復(fù)雜的內(nèi)部結(jié)構(gòu)日杈。 2、需要生成的對象內(nèi)部屬性本身相互依賴。
注意事項:與工廠模式的區(qū)別是:建造者模式更加關(guān)注與零件裝配的順序莉擒。
建造者模式:
建模:
Setp 1:
創(chuàng)建抽象產(chǎn)品協(xié)議 <IProduct>
.
#import <Foundation/Foundation.h>
@protocol IProduct <NSObject>
// 飲料
- (void)drink:(NSString *)drink;
// 食物
- (void)food:(NSString *)food;
// 小吃
- (void)snack::(NSString *)snack;
@end
Setp 2:
創(chuàng)建具體的產(chǎn)品類 KFCMeals
(實現(xiàn)了 <IProduct>
協(xié)議).
// .h
#import <Foundation/Foundation.h>
#import "IProduct.h"
@interface KFCMeals : NSObject<IProduct>
@end
// .m
#import "KFCMeals.h"
@implementation KFCMeals
// 飲料
- (void)drink:(NSString *)drink {
NSLog(@"選取KFC飲料為:%@",drink);
}
// 食物
- (void)food:(NSString *)food {
NSLog(@"選取KFC食物為:%@",food);
}
// 小吃
- (void)snack:(NSString *)snack {
NSLog(@"選取KFC小吃為:%@",snack);
}
@end
Setp 3:
創(chuàng)建抽象產(chǎn)品建造者協(xié)議 <IProductBuilder>
.
#import <Foundation/Foundation.h>
#import "IProduct.h"
@protocol IProductBuilder <NSObject>
// 建造飲料
- (id<IProductBuilder>)buildDrink:(NSString *)drink;
// 建造食物
- (id<IProductBuilder>)buildFood:(NSString *)food;
// 建造小吃
- (id<IProductBuilder>)buildSnack:(NSString *)snack;
// 建造套餐
- (id<IProduct>)buildMeals;
@end
Setp 4:
實現(xiàn)具體的產(chǎn)品類 KFCMealsBuilder
(實現(xiàn)了 <IProductBuilder>
協(xié)議).
// .h
#import <Foundation/Foundation.h>
#import "IProductBuilder.h"
@interface KFCMealsBuilder : NSObject<IProductBuilder>
@end
// .m
#import "KFCMealsBuilder.h"
#import "KFCMeals.h"
@interface KFCMealsBuilder()
@property (nonatomic ,strong)id<IProduct> meals;
@end
@implementation KFCMealsBuilder
// 套餐建造者 持有 套餐 的引用
- (instancetype)init {
if (self = [super init]) {
_meals = [[KFCMeals alloc] init];
}
return self;
}
// 這種鏈?zhǔn)秸{(diào)用就是典型的Builder的應(yīng)用
// 建造飲料
- (id<IProductBuilder>)buildDrink:(NSString *)drink {
[_meals drink:drink];
return self;
}
// 建造食物
- (id<IProductBuilder>)buildFood:(NSString *)food {
[_meals food:food];
return self;
}
// 建造小吃
- (id<IProductBuilder>)buildSnack:(NSString *)snack {
[_meals snack:snack];
return self;
}
// 建造套餐
- (id<IProduct>)buildMeals {
NSLog(@"生成了一個KFC套餐酿炸。");
return _meals;
}
@end
Setp 5:
創(chuàng)建統(tǒng)一組裝類 Director
(可省略不實現(xiàn)).
// .h
#import <Foundation/Foundation.h>
#import "IProductBuilder.h"
@interface Director : NSObject
// 構(gòu)造函數(shù)
- (instancetype)initWithBuilder:(id<IProductBuilder>)builder;
// 建造產(chǎn)品的方法
- (void)constructDrink:(NSString *)drink
food:(NSString *)food
snack:(NSString *)snack;
@end
// .m
#import "Director.h"
@interface Director()
@property (nonatomic, strong)id<IProductBuilder> builder;
@end
@implementation Director
- (instancetype)initWithBuilder:(id<IProductBuilder>)builder {
if (self = [super init]) {
_builder = builder;
}
return self;
}
- (void)constructDrink:(NSString *)drink
food:(NSString *)food
snack:(NSString *)snack {
[[[[_builder buildDrink:drink] buildFood:food] buildSnack:snack] buildMeals];
}
@end
Setp 6:測試
導(dǎo)入頭文件 #import "KFCMealsBuilder.h"
和 #import "Director.h"
測試一:(有統(tǒng)一組裝類的方法)
id<IProductBuilder> builder = [[KFCMealsBuilder alloc] init];
Director *dir = [[Director alloc] initWithBuilder:builder];
[dir constructDrink:@"牛奶" food:@"漢堡" snack:@"薯條"];
控制臺打印結(jié)果:
測試二:(無統(tǒng)一組裝類的方法)
開發(fā)中大多數(shù)情況下都是使用的該種方案。
id<IProductBuilder> builder = [[KFCMealsBuilder alloc] init];
[[[[builder buildDrink:@"牛奶"] buildSnack:@"雞塊"] buildFood:@"雞肉卷"] buildMeals];
控制臺打印結(jié)果:
到此建造者模式就完成了涨冀,如果有不同的見解歡迎討論~
代碼放在GitHub上了填硕,有需要查看的可以 -> 戳這里。
千里之行鹿鳖,始于足下扁眯。