iOS设计模式之生成器
2020/6/27 23:56:34
本文主要是介绍iOS设计模式之生成器,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
定义
生成器模式:将一个复杂对象的构建与它的表现分离,使得同样的构建过程可以创建不同的表现。
其整体思想是分离“什么”与“如何”。将复杂对象的构建过程分解为客户-指导者-生成器(client-director-builder)的关系。这样将更容易管理和复用整个过程。
使用场景
在以下情形时,自然会想到使用这一模式:
- 需要创建设计各种部件的复杂对象。创建对象的算法应该独立于部件的装配方式。常见于构建组合对象。
- 构建过程需要以不同的方式(例如,部件或表现的不同组合)构建对象
类图结构
生成器有三个角色,指导者Director,生成器Builder,产品Product,其三者的关系如下图所示
Director持有builder对象,构成聚合关系,用于构建产品Product。Director的construct方法实现为使用持有的builder执行buildPart方法。Builder是一个抽象接口,声明了一个buildPart方法。ConcreteBuilder实现继承的buildPart与getProduct方法,buildPart实现调用buildPartA,buildPartB,buildPartC方法来构建Product的不同细节。最后使用getProduct返回已经构建好的产品对象。
生成器与抽象工厂的对比
抽象工厂与生成器模式在抽象对象创建方面有许多相似之处。然而,两者却有着不同的设计理念。
- 生成器关注的是分布创建复杂对象,很多时候同一类型的对象可以以不同的方式创建。
- 抽象工厂的重点在于创建简单或者复杂产品的套件。
- 生成器在多步创建过程的最后一步返回产品,而抽象工厂则立即返回产品。
两者差异如下表:
生成器 | 抽象工厂 |
---|---|
构建复杂对象 | 构建简单或者复杂对象 |
以多步骤构建对象 | 以单一步骤构建对象 |
以多种方式构建对象 | 以单一方式构建对象 |
在构建过程的最后一步返回产品 | 立刻返回产品 |
专注一个特定的产品 | 强调一套产品 |
简单的说,生成器更注重过程的拆分,抽象工厂更注重结果的产生。
代码实现
下面将以构建游戏中的角色为例,使用生成器模式。
需求如下:我们需要构建两个游戏人物,敌人(Enemy)与游戏者(Player)。两种角色都有一些基本的基本特征,如力量(strength),耐力(stamina),智力(intelligence),敏捷(agility)和攻击力(aggressiveness)。每一个特征会影响角色的防御(Protection)和攻击(Power)能力。每项特征与人物的攻击或者防御的正反比关系如下:
防御 | 攻击 | |
---|---|---|
力量(strength) | ↑ | ↑ |
耐力(stamina) | ↑ | ↑ |
智力(intelligence) | ↑ | ↓ |
敏捷(agility) | ↑ | ↓ |
攻击力(aggressiveness) | ↓ | ↑ |
根据上述需求,设计出如下静态类图
XQChasingGame定义了createPlayer:builder与createEnemy:builder来创建游戏者与敌人。每个方法有一套不同的特殊因子,用来定义角色的特性。XQStandardCharacterBuilder是XQCharacterBuilder的一个子类,根据不同的特征因子创建实际的角色。构建完成后,XQStandardCharacterBuilder返回XQCharacter的实例。
- 构建角色对象XQCharacter
@interface XQCharacter : NSObject @property (nonatomic, assign) float protection; ![](https://user-gold-cdn.xitu.io/2020/6/24/172e213819f3556e?w=1435&h=697&f=png&s=118117) @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 XQCharacter - (instancetype)init{ if (self = [super init]){ self.protection = 1.0; self.power = 1.0; self.strength = 1.0; self.stamina = 1.0; self.intelligence = 1.0; self.agility = 1.0; self.aggressiveness = 1.0; } return self; } @end 复制代码
在初始化方法init中,给每个属性默认赋值1.0。
- 构建抽象类XQCharacterBuilder
@interface XQCharacterBuilder : NSObject @property (nonatomic, strong, readonly) XQCharacter *character; - (XQCharacterBuilder *)createCharacter; - (XQCharacterBuilder *)buildStrength:(float)value; - (XQCharacterBuilder *)buildStamina:(float)value; - (XQCharacterBuilder *)buildIntelligence:(float)value; - (XQCharacterBuilder *)buildAgility:(float)value; - (XQCharacterBuilder *)buildAggressiveness:(float)value; @end @interface XQCharacterBuilder () @property (nonatomic, strong, readwrite) XQCharacter *character; @end @implementation XQCharacterBuilder - (XQCharacterBuilder *)createCharacter{ self.character = [[XQCharacter alloc] init]; return self; } - (XQCharacterBuilder *)buildStrength:(float)value{ self.character.strength = value; return self; } - (XQCharacterBuilder *)buildStamina:(float)value{ self.character.stamina = value; return self; } - (XQCharacterBuilder *)buildIntelligence:(float)value{ self.character.intelligence = value; return self; } - (XQCharacterBuilder *)buildAgility:(float)value{ self.character.agility = value; return self; } - (XQCharacterBuilder *)buildAggressiveness:(float)value{ self.character.aggressiveness = value; return self; } @end 复制代码
XQCharacterBuilder中声明对应的对象创建与属性赋值接口,定义了默认的赋值行为,将对应的属性值赋给创建的对象character。
3.构建具体子类XQStandardCharacterBuilder
@interface XQStandardCharacterBuilder : XQCharacterBuilder - (XQCharacterBuilder *)buildStrength:(float)value; - (XQCharacterBuilder *)buildStamina:(float)value; - (XQCharacterBuilder *)buildIntelligence:(float)value; - (XQCharacterBuilder *)buildAgility:(float)value; - (XQCharacterBuilder *)buildAggressiveness:(float)value; @end @implementation XQStandardCharacterBuilder - (XQCharacterBuilder *)buildStrength:(float)value{ self.character.protection *= value; self.character.power *= value; return [super buildStrength:value]; } - (XQCharacterBuilder *)buildStamina:(float)value{ self.character.protection *= value; self.character.power *= value; return [super buildStamina:value]; } - (XQCharacterBuilder *)buildIntelligence:(float)value{ self.character.protection *= value; self.character.power /= value; return [super buildIntelligence:value]; } - (XQCharacterBuilder *)buildAgility:(float)value{ self.character.protection *= value; self.character.power /= value; return [super buildAgility:value]; } - (XQCharacterBuilder *)buildAggressiveness:(float)value{ self.character.protection /= value; self.character.power *= value; return [super buildAggressiveness:value]; } @end 复制代码
在XQStandardCharacterBuilder类声明中,重新声明重载父类的方法,以明确该类的任务与职责。
在XQStandardCharacterBuilder类实现中,针对每个基础属性对角色的防御和攻击的影响赋值。按照矩阵中的比例关系定义,影响角色的攻击和防御值。最后再调用父类的对应方法给属性赋值,并且返回自身。(返回自身self的好处我们下面会说到)
- 构建指导者XQChasingGame
@interface XQChasingGame : NSObject - (XQCharacter *)createPlayer:(XQCharacterBuilder *)builder; - (XQCharacter *)createEnemy:(XQCharacterBuilder *)builder; @end @implementation XQChasingGame - (XQCharacter *)createPlayer:(XQCharacterBuilder *)builder{ [[[[[[builder createCharacter] buildStrength:50.f] buildStamina:25.f] buildIntelligence:75.f] buildAgility:65.f] buildAggressiveness:35.f]; return builder.character; } - (XQCharacter *)createEnemy:(XQCharacterBuilder *)builder{ [[[[[[builder createCharacter] buildStrength:80.f] buildStamina:65.f] buildIntelligence:35.f] buildAgility:25.f] buildAggressiveness:95.f]; return builder.character; } @end 复制代码
XQChasingGame声明了创建游戏者与敌人的方法,内部实现根据需求要求角色属性不同传递不同的属性值。由于在具体子类XQStandardCharacterBuilder中,属性赋值方法都返回自身,这里就可以连续调用,构成单一语句。最后,将构建好的角色返回给外部使用。
- 客户端调用
XQStandardCharacterBuilder *builder = [XQStandardCharacterBuilder new]; XQChasingGame *game = [XQChasingGame new]; XQCharacter *player = [game createPlayer:builder]; XQCharacter *enemy = [game createEnemy:builder]; 复制代码
客户端生成XQStandardCharacterBuilder与XQChasingGame的实例,调用实例方法createPlayer与createEnemy创建游戏者与敌人角色。然后就可以使用两个角色对象投入游戏中。
总结
生成器模式能帮助构建涉及部件与表现的各种组合的对象。防止指导者Director成为一个庞大的类。将角色构建算法放在一个具体的XQCharacterBuilder中。
这篇关于iOS设计模式之生成器的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-10-05Swift语法学习--基于协议进行网络请求
- 2022-08-17Apple开发_Swift语言地标注释
- 2022-07-24Swift 初见
- 2022-05-22SwiftUI App 支持多语种 All In One
- 2022-05-10SwiftUI 组件参数简写 All In One
- 2022-04-14SwiftUI 学习笔记
- 2022-02-23Swift 文件夹和文件操作
- 2022-02-17Swift中使用KVO
- 2022-02-08Swift 汇编 String array
- 2022-01-30SwiftUI3.0页面反向传值