iOS 设计模式的应用 ⑤ 建造者模式

前言

    选择建造自己房子的人会把工程外包给承包商。单一承包商不能建造整个房子,他将其分解为几个部分,然后转包给几个实际的建筑商。客户告诉承包商房子里都有什么,然后承包商协调指导各房屋建筑商,决定需要做什么,应该如何建造。将建造过程分解为 客户-指导者(承包商)- 建造者(建筑商)的关系,过程更容易管理与复用,针对此类关系的设计模式称为建造者模式

什么是建造者模式

    有时,构建某些对象有多种不同方式,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。将一个复杂对象的构建与它的表现分离,使得同样的构建过程可以创建不同的表现。建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。

建造者模式的类图.png

传统建造者模式有4个角色。

  • Product: 最终要生成的对象
  • Builder: 构建者的抽象基类(有时会使用协议代替)。其定义了构建 Product的抽象步骤,其实体类需要实现这些步骤。其会包含一个用来返回最终产品的方法 Product getProduct()
  • ConcreteBuilder : Builder的实现类。
  • Director: 决定如何构建最终产品的算法. 其会包含一个负责组装的方法void Construct(Builder builder), 在这个方法中通过调用 builder 的方法,就可以设置 builder,等设置完成后,就可以通过builder的 getProduct() 方法获得最终的产品。

什么时候使用建造者模式

  • 一些基本部件不会变,而其组合经常变化的时候,构建需要以不同的方式构建对象

  • 需要生成的对象具有复杂的内部结构

  • 需要生成的对象内部属性本身相互依赖。

建造者模式的优缺点

优点

  1. 建造者独立,易扩展。
  2. 便于控制细节风险。

缺点

  1. 产品必须有共同点,范围有限制。
  2. 如内部变化复杂,会有很多的建造类。

建造者与抽象工厂的对比

建造者 抽象工厂
构建复杂对象 构建简单或复杂对象
以多个步骤构建对象 以单一步骤构建对象
以多种方式构建对象 以单一方式构建对象
在构建过程的最后一步返回产品 立刻返回产品
专注一个特定产品 强调一套产品

建造者模式的实现

    以假想的游戏角色为例,假定有两个类型的角色——敌人和游戏者,角色具有共同的基本特征,如力量,耐力,智力、敏捷和攻击力。每一个特征都影响着角色的防御(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

    接着,我们定义抽象的角色构建者 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。在这里,力量和耐力与防御和攻击成正比,智力和敏捷与防御成正比,与攻击成反比。根据不同特征因子实际构建角色。构建过程结束后,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

接下来,定义指导者 ChasingGame 类,其提供了创建游戏者和敌人角色的方法。

@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

最后,只需要通过 StandardCharacterBuilderChasingGame 就可以创建相应的游戏和敌人角色。

  
  CharacterBuilder *characterBuilder = [[[StandardCharacterBuilder alloc] init] autorelease];
  ChasingGame *game = [[[ChasingGame alloc] init] autorelease];
  
  Character *player = [game createPlayer:characterBuilder];
  Character *enemy = [game createEnemy:characterBuilder];

总结

    建造者模式能帮助构建涉及部件与表现的各种组合的对象。没有这一模式,知道构建对象所需细节的 Director 可能最终会变成一个庞大的类,带有无数用于构建同一个类的各种表现的内嵌算法。

你可能感兴趣的:(iOS 设计模式的应用 ⑤ 建造者模式)