前言
????選擇建造自己房子的人會(huì)把工程外包給承包商。單一承包商不能建造整個(gè)房子,他將其分解為幾個(gè)部分,然后轉(zhuǎn)包給幾個(gè)實(shí)際的建筑商。客戶告訴承包商房子里都有什么,然后承包商協(xié)調(diào)指導(dǎo)各房屋建筑商,決定需要做什么,應(yīng)該如何建造。將建造過程分解為 客戶-指導(dǎo)者(承包商)- 建造者(建筑商)的關(guān)系,過程更容易管理與復(fù)用,針對(duì)此類關(guān)系的設(shè)計(jì)模式稱為建造者模式。
什么是建造者模式
????有時(shí),構(gòu)建某些對(duì)象有多種不同方式,其通常由各個(gè)部分的子對(duì)象用一定的算法構(gòu)成;由于需求的變化,這個(gè)復(fù)雜對(duì)象的各個(gè)部分經(jīng)常面臨著劇烈的變化,但是將它們組合在一起的算法卻相對(duì)穩(wěn)定。將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表現(xiàn)分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表現(xiàn)。建造者模式(Builder Pattern)使用多個(gè)簡(jiǎn)單的對(duì)象一步一步構(gòu)建成一個(gè)復(fù)雜的對(duì)象。

傳統(tǒng)建造者模式有4個(gè)角色。
-
Product: 最終要生成的對(duì)象 -
Builder: 構(gòu)建者的抽象基類(有時(shí)會(huì)使用協(xié)議代替)。其定義了構(gòu)建Product的抽象步驟,其實(shí)體類需要實(shí)現(xiàn)這些步驟。其會(huì)包含一個(gè)用來返回最終產(chǎn)品的方法Product getProduct()。 -
ConcreteBuilder:Builder的實(shí)現(xiàn)類。 -
Director: 決定如何構(gòu)建最終產(chǎn)品的算法. 其會(huì)包含一個(gè)負(fù)責(zé)組裝的方法void Construct(Builder builder), 在這個(gè)方法中通過調(diào)用builder的方法,就可以設(shè)置builder,等設(shè)置完成后,就可以通過builder的getProduct()方法獲得最終的產(chǎn)品。
什么時(shí)候使用建造者模式
一些基本部件不會(huì)變,而其組合經(jīng)常變化的時(shí)候,構(gòu)建需要以不同的方式構(gòu)建對(duì)象
需要生成的對(duì)象具有復(fù)雜的內(nèi)部結(jié)構(gòu)
需要生成的對(duì)象內(nèi)部屬性本身相互依賴。
建造者模式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
- 建造者獨(dú)立,易擴(kuò)展。
- 便于控制細(xì)節(jié)風(fēng)險(xiǎn)。
缺點(diǎn)
- 產(chǎn)品必須有共同點(diǎn),范圍有限制。
- 如內(nèi)部變化復(fù)雜,會(huì)有很多的建造類。
建造者與抽象工廠的對(duì)比
| 建造者 | 抽象工廠 |
|---|---|
| 構(gòu)建復(fù)雜對(duì)象 | 構(gòu)建簡(jiǎn)單或復(fù)雜對(duì)象 |
| 以多個(gè)步驟構(gòu)建對(duì)象 | 以單一步驟構(gòu)建對(duì)象 |
| 以多種方式構(gòu)建對(duì)象 | 以單一方式構(gòu)建對(duì)象 |
| 在構(gòu)建過程的最后一步返回產(chǎn)品 | 立刻返回產(chǎn)品 |
| 專注一個(gè)特定產(chǎn)品 | 強(qiáng)調(diào)一套產(chǎn)品 |
建造者模式的實(shí)現(xiàn)
????以假想的游戲角色為例,假定有兩個(gè)類型的角色——敵人和游戲者,角色具有共同的基本特征,如力量,耐力,智力、敏捷和攻擊力。每一個(gè)特征都影響著角色的防御(protection)和攻擊(Power)能力,因此我們定義一個(gè)角色類 Character:
@interface Character : NSObject
@property (nonatomic, assign) float protection;
@property (nonatomic, assign) float power;
@property (nonatomic, assign) float strength;
@property (nonatomic, assign) float stamina;
@property (nonatomic, assign) float intelligence;
@property (nonatomic, assign) float agility;
@property (nonatomic, assign) float aggressiveness;
@end
@implementation Character
- (instancetype)init
{
self = [super init];
if (self) {
_protection = 1.0;
_power = 1.0;
_strength = 1.0;
_stamina = 1.0;
_intelligence = 1.0;
_agility = 1.0;
_aggressiveness = 1.0;
}
return self;
}
@end
????接著,我們定義抽象的角色構(gòu)建者 CharacterBuilder:
@interface CharacterBuilder : NSObject
{
@protected
Character *_character;
}
@property (nonatomic, readonly) Character *character;
- (CharacterBuilder *) buildNewCharacter;
- (CharacterBuilder *) buildStrength:(float) value;
- (CharacterBuilder *) buildStamina:(float) value;
- (CharacterBuilder *) buildIntelligence:(float) value;
- (CharacterBuilder *) buildAgility:(float) value;
- (CharacterBuilder *) buildAggressiveness:(float) value;
@end
@implementation CharacterBuilder
@synthesize character=_character;
- (CharacterBuilder *) buildNewCharacter
{
_character = [[Character alloc] init];
return self;
}
- (CharacterBuilder *) buildStrength:(float) value
{
_character.strength = value;
return self;
}
- (CharacterBuilder *) buildStamina:(float) value
{
_character.stamina = value;
return self;
}
- (CharacterBuilder *) buildIntelligence:(float) value
{
_character.intelligence = value;
return self;
}
- (CharacterBuilder *) buildAgility:(float) value
{
_character.agility = value;
return self;
}
- (CharacterBuilder *) buildAggressiveness:(float) value
{
_character.aggressiveness = value;
return self;
}
@end
????StandardCharacterBuilder 是具體的 CharacterBuilder。在這里,力量和耐力與防御和攻擊成正比,智力和敏捷與防御成正比,與攻擊成反比。根據(jù)不同特征因子實(shí)際構(gòu)建角色。構(gòu)建過程結(jié)束后,StandardCharacterBuilder 將返回 Character的實(shí)例。
@interface StandardCharacterBuilder : CharacterBuilder
{
}
// overriden methods from the abstract CharacterBuilder
- (CharacterBuilder *) buildStrength:(float) value;
- (CharacterBuilder *) buildStamina:(float) value;
- (CharacterBuilder *) buildIntelligence:(float) value;
- (CharacterBuilder *) buildAgility:(float) value;
- (CharacterBuilder *) buildAggressiveness:(float) value;
@end
@implementation StandardCharacterBuilder
- (CharacterBuilder *) buildStrength:(float) value
{
// update the protection value of the character
_character.protection *= value;
// update the power value of the character
_character.power *= value;
// finally set the strength value and return this builder
return [super buildStrength:value];
}
- (CharacterBuilder *) buildStamina:(float) value
{
// update the protection value of the character
_character.protection *= value;
// update the power value of the character
_character.power *= value;
// finally set the strength value and return this builder
return [super buildStamina:value];
}
- (CharacterBuilder *) buildIntelligence:(float) value
{
// update the protection value of the character
_character.protection *= value;
// update the power value of the character
_character.power /= value;
// finally set the strength value and return this builder
return [super buildIntelligence:value];
}
- (CharacterBuilder *) buildAgility:(float) value
{
// update the protection value of the character
_character.protection *= value;
// update the power value of the character
_character.power /= value;
// finally set the strength value and return this builder
return [super buildAgility:value];
}
- (CharacterBuilder *) buildAggressiveness:(float) value
{
// update the protection value of the character
_character.protection /= value;
// update the power value of the character
_character.power *= value;
// finally set the strength value and return this builder
return [super buildAggressiveness:value];
}
@end
接下來,定義指導(dǎo)者 ChasingGame 類,其提供了創(chuàng)建游戲者和敵人角色的方法。
@interface ChasingGame : NSObject
{
}
- (Character *) createPlayer:(CharacterBuilder *) builder;
- (Character *) createEnemy:(CharacterBuilder *) builder;
@end
@implementation ChasingGame
- (Character *) createPlayer:(CharacterBuilder *) builder
{
// an alternative way to build a character
[[[[[[builder buildNewCharacter]
buildStrength:50.0]
buildStamina:25.0]
buildIntelligence:75.0]
buildAgility:65.0]
buildAggressiveness:35.0];
return [builder character];
}
- (Character *) createEnemy:(CharacterBuilder *) builder
{
[builder buildNewCharacter];
[builder buildStrength:80.0];
[builder buildStamina:65.0];
[builder buildIntelligence:35.0];
[builder buildAgility:25.0];
[builder buildAggressiveness:95.0];
return [builder character];
}
@end
最后,只需要通過 StandardCharacterBuilder 和 ChasingGame 就可以創(chuàng)建相應(yīng)的游戲和敵人角色。
CharacterBuilder *characterBuilder = [[[StandardCharacterBuilder alloc] init] autorelease];
ChasingGame *game = [[[ChasingGame alloc] init] autorelease];
Character *player = [game createPlayer:characterBuilder];
Character *enemy = [game createEnemy:characterBuilder];
總結(jié)
????建造者模式能幫助構(gòu)建涉及部件與表現(xiàn)的各種組合的對(duì)象。沒有這一模式,知道構(gòu)建對(duì)象所需細(xì)節(jié)的 Director 可能最終會(huì)變成一個(gè)龐大的類,帶有無數(shù)用于構(gòu)建同一個(gè)類的各種表現(xiàn)的內(nèi)嵌算法。