前言
????選擇建造自己房子的人會把工程外包給承包商功氨。單一承包商不能建造整個房子序苏,他將其分解為幾個部分,然后轉(zhuǎn)包給幾個實際的建筑商捷凄〕老辏客戶告訴承包商房子里都有什么,然后承包商協(xié)調(diào)指導(dǎo)各房屋建筑商跺涤,決定需要做什么匈睁,應(yīng)該如何建造。將建造過程分解為 客戶-指導(dǎo)者(承包商)- 建造者(建筑商)的關(guān)系桶错,過程更容易管理與復(fù)用航唆,針對此類關(guān)系的設(shè)計模式稱為建造者模式。
什么是建造者模式
????有時院刁,構(gòu)建某些對象有多種不同方式糯钙,其通常由各個部分的子對象用一定的算法構(gòu)成;由于需求的變化退腥,這個復(fù)雜對象的各個部分經(jīng)常面臨著劇烈的變化任岸,但是將它們組合在一起的算法卻相對穩(wěn)定。將一個復(fù)雜對象的構(gòu)建與它的表現(xiàn)分離狡刘,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表現(xiàn)享潜。建造者模式(Builder Pattern)使用多個簡單的對象一步一步構(gòu)建成一個復(fù)雜的對象。
傳統(tǒng)建造者模式有4個角色颓帝。
-
Product
: 最終要生成的對象 -
Builder
: 構(gòu)建者的抽象基類(有時會使用協(xié)議代替)米碰。其定義了構(gòu)建Product
的抽象步驟窝革,其實體類需要實現(xiàn)這些步驟。其會包含一個用來返回最終產(chǎn)品的方法Product getProduct()
吕座。 -
ConcreteBuilder
:Builder
的實現(xiàn)類虐译。 -
Director
: 決定如何構(gòu)建最終產(chǎn)品的算法. 其會包含一個負責(zé)組裝的方法void Construct(Builder builder)
, 在這個方法中通過調(diào)用builder
的方法吴趴,就可以設(shè)置builder
漆诽,等設(shè)置完成后,就可以通過builder的getProduct()
方法獲得最終的產(chǎn)品锣枝。
什么時候使用建造者模式
一些基本部件不會變厢拭,而其組合經(jīng)常變化的時候,構(gòu)建需要以不同的方式構(gòu)建對象
需要生成的對象具有復(fù)雜的內(nèi)部結(jié)構(gòu)
需要生成的對象內(nèi)部屬性本身相互依賴撇叁。
建造者模式的優(yōu)缺點
優(yōu)點
- 建造者獨立供鸠,易擴展。
- 便于控制細節(jié)風(fēng)險陨闹。
缺點
- 產(chǎn)品必須有共同點楞捂,范圍有限制。
- 如內(nèi)部變化復(fù)雜趋厉,會有很多的建造類寨闹。
建造者與抽象工廠的對比
建造者 | 抽象工廠 |
---|---|
構(gòu)建復(fù)雜對象 | 構(gòu)建簡單或復(fù)雜對象 |
以多個步驟構(gòu)建對象 | 以單一步驟構(gòu)建對象 |
以多種方式構(gòu)建對象 | 以單一方式構(gòu)建對象 |
在構(gòu)建過程的最后一步返回產(chǎn)品 | 立刻返回產(chǎn)品 |
專注一個特定產(chǎn)品 | 強調(diào)一套產(chǎn)品 |
建造者模式的實現(xiàn)
????以假想的游戲角色為例,假定有兩個類型的角色——敵人和游戲者君账,角色具有共同的基本特征繁堡,如力量,耐力乡数,智力椭蹄、敏捷和攻擊力。每一個特征都影響著角色的防御(protection)和攻擊(Power)能力瞳脓,因此我們定義一個角色類 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ù)不同特征因子實際構(gòu)建角色。構(gòu)建過程結(jié)束后拳球,StandardCharacterBuilder
將返回 Character
的實例审姓。
@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)的各種組合的對象酬姆。沒有這一模式嗜桌,知道構(gòu)建對象所需細節(jié)的 Director 可能最終會變成一個龐大的類,帶有無數(shù)用于構(gòu)建同一個類的各種表現(xiàn)的內(nèi)嵌算法辞色。