APP & program

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

2022-05-08  本文已影响0人  _涼城

前言

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

什么是建造者模式

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

建造者模式的类图.png

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

什么时候使用建造者模式

建造者模式的优缺点

优点

  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 可能最终会变成一个庞大的类,带有无数用于构建同一个类的各种表现的内嵌算法。

上一篇 下一篇

猜你喜欢

热点阅读