iOS设计模式——生成器模式

选择建造自己的房子的人会把工程外包给承包商。单一承包商不能建造整个房子,他将其分解为几个部分,然后转包给几个实际的建筑商,他们懂得如何将零部件组装起来。房子由由风格、颜色和尺寸各不相同的部件组成。客户告诉承包商房子里都要有什么,然后承包商协调各房屋建筑商,决定需要做什么。应该如何建造,建筑商就如何施工。建房子是个复杂过程,单凭一双手就想建房子,即便可能也非常困难。如果承包商(指导者)与懂得如何建造的建筑商相互协调,这一过程简单得多且更易管理。

有时,构建某些对象有多种不同方式。如果这些逻辑包含在构建这些对象的类的单一方法中,构建的逻辑就会变得非常复杂(比如,针对各种构建需求的一大片嵌套if-else或者switch-case语句)。如果能够把构建过程分解为客户——指导者——生成器的关系,那么过程将更容易管理与复用。针对此类关系的设计模式称为生成器。

何为生成器模式?

除了客户与其所要的产品,生成器模式还包含两个重要角色:Director(指导者)和Builder(生成器)。Builder知道究竟如何在缺少某些特定信息的情况下建造产品。Director知道Builder应该建造什么,以参数向其提供缺少的信息来建造特定产品。虽然Director知道Builder应该建造什么,这并不意味着Director知道具体Builder究竟是什么。

Builder是一个抽象接口,声明了一个builderPart方法,该方法由ConcreteBuilder实现,以构造实际产品(Product)。ConcreteBuilder有个getResult方法,向客户端返回构建完毕的Product。Director定义了一个construct方法,命令Builder的实例去buildPart。Director和Builder形成一种聚合关系。这意味着Builder是一个组成部分,与Director结合,以使整个模式运转,但同时,Director并不负责Builder的生存期。

生成器模式:将一个复杂对象的构建和它的表现分离,使得同样的构建过程可以创建不同的表现。

何时使用生成器模式?

@:需要创建涉及各种部件的复杂对象。创建对象的算法应该独立于部件的装配方式。

@:构建过程需要以不同的方式(比如,部件或表现的不同组合)构建对象。

生成器模式与抽象工厂的区别

生成器模式:构建复杂对象,以多个步骤构建对象,以多种方式构建对象,在构建过程的最后一步返回产品,专注一个特定产品。

抽象工厂模式:构建简单或复杂对象,以单一步骤构建对象,以单一方式构建对象,立刻返回产品,强调一套产品。

生成器模式的应用

通过构建带有各类角色的追逐游戏,涉及各类对象、财产或角色的游戏,其构建过程会相当复杂,可以通过生成器模式,把构建角色的算法(如何构建角色)与构建什么角色分离开来。

我们将以假想的追逐游戏为例,演示如何实现生成器模式。假定有两种类型的角色——敌人和游戏者。敌人将追逐游戏者,玩家决定游戏者往哪儿走。路上可能有障碍。两种角色有一些共同的基本特征,如力量、耐力、智力、敏捷和攻击力。每一特征都影响角色的防御(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

时间: 2024-11-03 21:10:49

iOS设计模式——生成器模式的相关文章

设计模式-生成器模式

前言 点击查看:设计模式系列 生成器模式(建造者模式/builder) 定义:将一个复杂的对象,分成多分,使同样的构建过程,能有不同的表示,这样的设计模式被称为建造者模式. 举例说明: 李嘉诚的遗嘱执行: 财产(产品角色):李嘉诚拥有众多复杂的财产框架,这里以现金与物品入例. 遗嘱(建造者):相当于建造者,分配现金与物品. 具体遗嘱(具体建造者):1.给大儿子的财产分配,2,给小儿子的财产分配. 律师(指导者角色):按照具体的遗嘱指令分配财产. 例子类图: 庞大的财产结构代码: // 财产(复杂

Java设计模式--生成器模式

将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示. Builder Pattern Separate the construction of a complex object from its representation so that the same construction process can create different representations. 类图 模式的结构与使用 生成器模式的结构中包括四个角色. 产品(Product):具体生成器要构造的复

跟着实例学习设计模式-生成器模式(builder)

生成器模式是创建型设计模式. 设计意图:将一个复杂的类表示与其构造相分离,使得相同的构建过程能够得出不同的表示. 实例类图: IVehicleBuilder:抽象建造者,为创建一个Vehicle对象并创建它的相关部件指定的抽象接口,把产品的生产过程分解为不同的步骤,从而使具体的建造者在具体的建造步骤上具有更多弹性,从而创造出不同表示的产品.(这里就是小车和卡车) CarBuilder.TrunkBuilder:具体建造者,实现IVehicleBuilder接口,构造和装配产品的各个部件定义并明确

iOS设计模式 - 生成器

原理图 说明 1. 将构建复杂对象的过程拆分成一个一个的模块,通过统一的指导者来指导对象的构建过程称之为生成器模式 2. 生成器模式适合用于构建组合的对象 源码 https://github.com/YouXianMing/BuilderPattern // // CarBuilder.h // BuilderPattern // // Created by YouXianMing on 15/9/14. // Copyright (c) 2015年 YouXianMing. All right

设计模式——生成器模式

这次来看下生成器模式,先来看下类图: 那么来说下特点吧: 将一个复杂对象的创建过程封装起来 允许对象通过多个步骤来创建,并且可以改变过程 实现可以被替换 隐藏了内部实现 来看下代码吧: public abstract class AbstractCarBuilder { public Car car = new Car(); public abstract AbstractCarBuilder builderName(String name); public abstract AbstractC

ios设计模式—策略模式

其实ios的设计模式有很多种,在实际应用中我们应该可以的去使用一些设计模式去规范和丰富我们的代码~~嘿嘿 其实策略模式就是将我们代码中的复杂逻辑抽象成一个对象去处理,这会大大减少代码量,并且去使我们的逻辑看起来更有条理. 拿if else为例可以将一个复杂的判断逻辑写到一个抽象的基类中,在其中进行判断再运用继承和多态的原理去分别执行不同的业务逻辑,这样会在控制器中减少代码量 控制器代码:通过传入判断条件去控制执行逻辑 // // ViewController.m // strategyDemo

实际案例讲解iOS设计模式——MVC模式

MVC模式是iOS编程中提到的最多次的设计模式,也是使用最频繁的设计模式之一.网络上有很多的MVC模式的分析文章,但都是从原理上来解释,很少能找到配套的案例来说明到底在实际的项目中要如何的使用这种模式.小编在经过详细的研究.对比和实验了之后,总结了一下这个模式的一些简单使用方法,希望能起一个抛砖引玉的作用,使得对MVC默认的同学能依葫芦画瓢的了解MVC模式的使用方法,并以此类推出更多.更好的方法出来. 这篇文章先从老生常谈的MVC设计模式的原理说起,然后配上一个简单的案例,以演示如何将一个常规的

iOS设计模式 - 命令模式

命令模式 前言: 命令对象封装了如何对目标执行指令的信息,因此客户端或调用者不必了解目标的任何细节,却仍可以对他执行任何已有的操作.通过把请求封装成对象,客 户端可 以把它参数化并置入队列或日志中,也能够支持可撤销操作.命令对象将一个或多个动作绑定到特定的接收器.命令模式消除了作为对象的动作和执行它的接收器之 间的绑定. 正文内容大纲: 1.电视机.遥控器与接收器之间的关系2.改变一个视图的明暗程度(未使用命令模式)3.命令模式介绍4.改变一个视图的明暗程度(使用命令模式)5.附录 命令模式 1

iOS设计模式---访问者模式

一个简单的Car模型,含有1台Engine.4个Wheel,使用访问者模式添加对Car的升级与维修操作. 定义Engine类: // //  NimoEngine.h //  VisitorDemo // //  Created by fu zheng on 15/8/12. //  Copyright (c) 2015年 FuZheng. All rights reserved. // #import <Foundation/Foundation.h> #import "NimoC