iOS設計模式——生成器模式

    選擇建造本身的房子的人會把工程外包給承包商。單一承包商不能建造整個房子,他將其分解爲幾個部分,而後轉包給幾個實際的建築商,他們懂得如何將零部件組裝起來。房子由由風格、顏色和尺寸各不相同的部件組成。客戶告訴承包商房子裏都要有什麼,而後承包商協調各房屋建築商,決定須要作什麼。應該如何建造,建築商就如何施工。建房子是個複雜過程,單憑一雙手就想建房子,即使可能也很是困難。若是承包商(指導者)與懂得如何建造的建築商相互協調,這一過程簡單得多且更易管理。git

    有時,構建某些對象有多種不一樣方式。若是這些邏輯包含在構建這些對象的類的單一方法中,構建的邏輯就會變得很是複雜(好比,針對各類構建需求的一大片嵌套if-else或者switch-case語句)。若是可以把構建過程分解爲客戶——指導者——生成器的關係,那麼過程將更容易管理與複用。針對此類關係的設計模式稱爲生成器。github

何爲生成器模式?算法

    除了客戶與其所要的產品,生成器模式還包含兩個重要角色:Director(指導者)和Builder(生成器)。Builder知道究竟如何在缺乏某些特定信息的狀況下建造產品。Director知道Builder應該建造什麼,以參數向其提供缺乏的信息來建造特定產品。雖然Director知道Builder應該建造什麼,這並不意味着Director知道具體Builder到底是什麼。 
c#

    Builder是一個抽象接口,聲明瞭一個builderPart方法,該方法由ConcreteBuilder實現,以構造實際產品(Product)。ConcreteBuilder有個getResult方法,向客戶端返回構建完畢的Product。Director定義了一個construct方法,命令Builder的實例去buildPart。Director和Builder造成一種聚合關係。這意味着Builder是一個組成部分,與Director結合,以使整個模式運轉,但同時,Director並不負責Builder的生存期。設計模式

    生成器模式:將一個複雜對象的構建和它的表現分離,使得一樣的構建過程能夠建立不一樣的表現。ui

什麼時候使用生成器模式?atom

    @:須要建立涉及各類部件的複雜對象。建立對象的算法應該獨立於部件的裝配方式。spa

    @:構建過程須要以不一樣的方式(好比,部件或表現的不一樣組合)構建對象。設計

生成器模式與抽象工廠的區別code

    生成器模式:構建複雜對象,以多個步驟構建對象,以多種方式構建對象,在構建過程的最後一步返回產品,專一一個特定產品。

    抽象工廠模式:構建簡單或複雜對象,以單一步驟構建對象,以單一方式構建對象,馬上返回產品,強調一套產品。

生成器模式的應用

    經過構建帶有各種角色的追逐遊戲,涉及各種對象、財產或角色的遊戲,其構建過程會至關複雜,能夠經過生成器模式,把構建角色的算法(如何構建角色)與構建什麼角色分離開來。

    咱們將以假想的追逐遊戲爲例,演示如何實現生成器模式。假定有兩種類型的角色——敵人和遊戲者。敵人將追逐遊戲者,玩家決定遊戲者往哪兒走。路上可能有障礙。兩種角色有一些共同的基本特徵,如力量、耐力、智力、敏捷和攻擊力。每一特徵都影響角色的防護(Protection)與攻擊(Power)能力。防護因子反應了角色防護攻擊的能力,而攻擊因子反映了攻擊對手的能力。特徵與防護或攻擊因子成正比或反比關係。

    力量和耐力與防護和攻擊成正比例。擁有較高力量與耐力因子的角色,也多一些自我防護與反擊的機會。智力和敏捷與防護因子成正比例,而與攻擊成反比例。咱們假定是這樣的關係。

    咱們定義一個ChasingGame的類,它有兩個方法,用以建立兩種類型的角色——遊戲者與敵人。CharacterBuilder基於前述矩陣所示各類特徵的關係構建角色。每一特徵因子影響被構建的角色的特性。顯示其靜態關係的類圖以下:

    ChasingGame定義了createPlayer:builder和createEnemy:builder,經過CharacterBuilder的實例建立遊戲者和敵人角色。每一個方法有一套不一樣的特徵因子,用來定義角色的特性。StandardCharacterBuilder是具體的CharacterBuilder,它根據不一樣特徵因子實際構建角色。構建過程結束後,StandaraCharacterBuilder將返回Character的實例。Character的代碼以下:

#import <Foundation/Foundation.h>

@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

    Character定義全部類型角色共有的一套特徵,包括防護、攻擊、力量、耐力、智力、敏捷和攻擊力。Character的實現僅僅是定義了一個init方法和幾個屬性的同步,代碼以下:

#import "Character.h"

@implementation Character

- (id)init {
    if (self = [super init]) {
        _protection = 1.0;
        _power = 1.0;
        _strength = 1.0;
        
        _stamina = 1.0;
        _intelligence = 1.0;
        _agility = 1.0;
        
        _aggressiveness = 1.0;
    }
    
    return self;
}

@end

    Character的實例不知道如何把本身構建成有意義的角色,因此才須要CharacterBuilder基於先前定義的特徵關係,構建有意義的角色。CharacterBuilder的代碼以下:

#import "StandarCharacterBuilder.h"

@implementation StandarCharacterBuilder

- (CharacterBuilder *)buildStrength:(float)value {
    // 更新角色的防護值
    self.character.protection *= value;
    
    // 更新角色的攻擊值
    self.character.power *= value;
    
    // 最後設定力量值並返回今生成器
    return [super buildStrength:value];
}

- (CharacterBuilder *)buildStamia:(float)value {
    // 更新角色的防護值
    self.character.protection *= value;
    
    // 更新角色的攻擊值
    self.character.power *= value;
    
    // 最後設定男離職並返回今生成器
    return [super buildStamia:value];
}

- (CharacterBuilder *)buildIntelligence:(float)value {
    // 更新角色的防護值
    self.character.protection *= value;
    
    // 更新角色的攻擊值
    self.character.power /= value;
    
    // 最後設定智力值並返回生成器
    return [super buildIntelligence:value];
}

- (CharacterBuilder *)buildAgility:(float)value {
    // 更新角色的防護值
    self.character.protection *= value;
    
    // 更新角色的攻擊值
    self.character.power /= value;
    
    // 最後設定敏捷值並返回今生成器
    return [super buildAgility:value];
}

- (CharacterBuilder *)buildAggressiveness:(float)value {
    // 更新角色的防護值
    self.character.protection /= value;
    
    // 更新角色的攻擊值
    self.character.power *= value;
    
    // 最後設定攻擊力值並返回今生成器
    return [super buildAggressiveness:value];
}

@end

    接下來看看ChasingGame是如何使用StandardCharacterBuilder來構建各類角色的,代碼以下:

#import <Foundation/Foundation.h>
#import "StandarCharacterBuilder.h"
@interface ChasingGame : NSObject

- (Character *)createPlayer:(CharacterBuilder *)builder;
- (Character *)createEnemy:(CharacterBuilder *)builder;

@end
#import "ChasingGame.h"

@implementation ChasingGame

- (Character *)createPlayer:(CharacterBuilder *)builder {
    [builder buildCharacter];
    [builder buildStrength:50.0];
    [builder buildStamia:25.0];

    [builder buildIntelligence:75.0];
    [builder buildAgility:65.0];
    [builder buildAggressiveness:35.0];
    
    return [builder character];
}

- (Character *)createEnemy:(CharacterBuilder *)builder {
    [builder buildCharacter];
    [builder buildStrength:80.0];
    [builder buildStamia:65.0];
    
    [builder buildIntelligence:35.0];
    [builder buildAgility:25.0];
    [builder buildAggressiveness:95.0];
    
    return [builder character];
}

@end

   ChasingGame的實例在createPlayer:方法中構建了一個遊戲者角色,其特徵因子分別爲力量50.0、耐力25.0、智力75.0、敏捷65.0、攻擊力35.0.在createEnemy:方法中,也是相似的,只是使用了不一樣的特徵因子。咱們來看下在客戶單怎麼來使用,代碼以下:

#import "ViewController.h"
#import "Character.h"
#import "CharacterBuilder.h"
#import "StandarCharacterBuilder.h"
#import "ChasingGame.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // 具體生成器
    CharacterBuilder *characterBuilder = [[StandarCharacterBuilder alloc] init];
    // 指導者
    ChasingGame *chasingGame = [[ChasingGame alloc] init];
    
    Character *player = [chasingGame createPlayer:characterBuilder];
    Character *enemy = [chasingGame createEnemy:characterBuilder];
    
    NSLog(@"player protection : %f aggressiveness : %f", player.protection, player.aggressiveness);
    NSLog(@"player protection : %f aggressiveness : %f", enemy.protection, enemy.aggressiveness);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

    輸出信息以下:

2015-09-09 22:06:39.435 BuilderPatternDemo[3078:74535] player protection : 174107.140625 aggressiveness : 35.000000
2015-09-09 22:06:39.435 BuilderPatternDemo[3078:74535] player protection : 47894.738281 aggressiveness : 95.000000

    生成器模式能幫助構建涉及部件與表現的各類組合對象,使用生成器模式就會帶來極大的便利性。

    Demo連接地址:https://github.com/guoshimeihua/BuilderPatternDemo

相關文章
相關標籤/搜索