设计模式三板斧之--生成器

第一板斧

何为生成器模式?

生成器模式(Builder): 将一个复杂对象的构建与它的表现分离,使得一样的构建过程能够建立不一样的表现。

what?说啥呢?

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

解决什么问题

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

  • 建造者模式是一步一步建立一个复杂的对象,它容许用户只经过指定复杂对象的类型和内容就能够构建它们,用户不须要知道内部的具体构建细节。建造者模式属于对象建立型模式。根据中文翻译的不一样,建造者模式又能够称为生成器模式。ui

  • 若是咱们用了生成器模式,那么用户就只需指定须要建造的类型就能够到带到它们,而建造的过程和细节就不需知道了。atom

第二板斧

生成器结构

建造者模式包含以下角色:spa

  • Builder:抽象建造者翻译

    Builder是一个抽象接口,声明了一个buildPart方法,该builder方法由ConcreteBuilder实现,以构造实际产品(Product).
  • ConcreteBuilder:具体建造者设计

  • Director:指挥者code

    Director定义了一个construct方法,命令Builder的实例去buildPart。Director和Builder造成一种聚合关系.
  • Product:产品角色对象

类图blog

clipboard.png

时序图继承

clipboard.png

第三板斧

生成器与抽象工厂的对比

二者有类似之处。可是,一方面生成器关注的是分步建立复杂对象,不少时候同一类型的对象能够以不一样的方式建立。另外一方面,抽象工厂的重点在于建立简单或复杂产品的套件,生成器在多步建立过程的最后一步返回产品,而抽象工厂会当即返回产品

生成器 抽象工厂
构建复杂对象 构件简单或复杂对象
以多个步骤构建对象 以单一步骤构建对象
以多种方式构建对象 以单一方式构建对象
在构建过程的最后一步返回产品 马上返回产品
专一一个特定产品 强调一套产品

代码演示

如今以生产车的例子做演示,这里的三个角色分别是:
  • Car (Product)

  • CarBuilder (Builder)

  • CarDirector (Director)

用户须要SUV和小汽车,对应的ConcreteBuilder分别是:
  • SUVCarBuilder

  • SedanCarBuilder

产品 Car
@interface Car : NSObject

@property (nonatomic, assign) NSUInteger wheel; // 轮毅
@property (nonatomic, assign) CGFloat engine; // 发动机
@property (nonatomic, assign) CGFloat chassis; // 底盘
@property (nonatomic, assign) CGSize size; // 车身

/// 跑起来
- (void)run;

@end
建造者 CarBuilder.h
@interface CarBuilder : NSObject

@property (nonatomic, strong) Car *car;

/// 组装车轮
- (void)buildWheel;

/// 组装车身
- (void)buildBody;

/// 组装发动机
- (void)buildEngie;

/// 组装底盘    
- (void)buildChassis;

/// 获得产品
- (Car *)getCar;

@end
因为它是抽象类,iOS中并无抽象类的概念,先这样实现CarBuilder.m
@implementation CarBuilder

- (instancetype)init
{
    self = [super init];
    if (self) {
        _car = [[Car alloc] init];
    }
    return self;
}

/// 组装车轮
- (void)buildWheel
{
    NSAssert(NO, @"必须建立具体车轮");
    self.car.wheel = 0;
}

/// 组装车身
- (void)buildBody
{
    NSAssert(NO, @"必须建立具体车身");
    self.car.size = CGSizeZero;
}

/// 组装发动机
- (void)buildEngie
{
    NSAssert(NO, @"必须建立具体发动机");
    self.car.engine = 0;
}

/// 组装底盘
- (void)buildChassis
{
    NSAssert(NO, @"必须建立具体底盘");
    self.car.chassis = 0;
}

/// 获得产品
- (Car *)getCar
{
    // doSomething...
    return self.car;
}
这里以生产SUV为例,小轿车也同样。SUVBuilder继承CarBuilder,只需实现这几个建造方法便可
@implementation SUVCarBuilder

/// 组装车轮
- (void)buildWheel
{
    self.car.wheel = 20;
}

/// 组装车身
- (void)buildBody
{
    self.car.size = CGSizeMake(100, 50);
}

/// 组装发动机
- (void)buildEngie
{
    self.car.engine = 2.5f; 
}

/// 组装底盘
- (void)buildChassis
{
    self.car.chassis = 30;
}

@end
最后client调用
- (void)viewDidLoad {
    [super viewDidLoad];
    self.carDirdector = [[CarDirector alloc] init];
}

- (IBAction)SUVButtonTap:(id)sender
{
    SUVCarBuilder *SUVBuilder = [[SUVCarBuilder alloc] init];
    self.carDirdector.builder = SUVBuilder;
    Car *SUVCar = [self.carDirdector construct];
    [SUVCar run];
}

- (IBAction)SedanButtonTap:(id)sender
{
    SedanCarBuilder *SedanBuilder = [[SedanCarBuilder alloc] init];
    self.carDirdector.builder = SedanBuilder;
    Car *SedanCar = [self.carDirdector construct];
    [SedanCar run];
}
相关文章
相关标签/搜索