风海: 铜锣老兄,我最近买了台不错的电脑诶,你要不要看看装备?

铜锣: 来来,我过目过目。

风海: 你看看啊。

类型 装备
主体 Intel 天逸510S
内存 DDR4
视频接口 VGA/HDMI
CPU 4核i3
显卡 集成
硬盘 西部数据7200rpm
输入设备 罗技鼠标+硬盘
显示器 三星xx型号

铜锣: 感觉不错嘛,回头拿过来跑跑分。

风海: 其实有一些参数我还没放上来呢,我在想,如果有一天我是负责写代码处理这一块的录入,那我建一个Computer类岂不是结构函数要包括这么一大坨数据。

铜锣: 啊哈,你这个类真包括这么大坨数据的话,它便是典型的杂乱构建问题了。

风海: 哦?那么对于杂乱目标的构建,有什么好的解决方案吗?

铜锣: 规划形式却是有这么一个形式是专门解决这个问题的,叫制作者形式,或者叫生成器形式,还有一些其他译名,不过英文名却是一致的,叫Builder Pattern

风海: 说到创立目标,咱们之前也聊过工厂形式,这个制作者形式也负责创立目标,两者有什么区别吗?

铜锣: 当然有区别,工厂形式解决的是类型多样性的问题,制作者形式解决的是类型内部结构杂乱性的问题。

风海: 这样,那你以代码为例,如果把我这台电脑写作一个类Computer,根据客户供给的信息进行个性化装备,那么这个类应该怎么写。

铜锣: 我先从根底写起,比方这样:

swift
仿制代码
class Computer {
  var body: String = ""
  var memory: String = ""
    var description: String {
        "body = (body) memory = (memory)"
    }
}

风海: 看到了,你写了一个Computer类,供给了两个特点,然后呢,没看到有Builder啊。

风海: 别急,这仅仅起步,我往下写。

swift
仿制代码
class Computer {
  var body: String = ""
  var memory: String = ""
    var description: String {
        "body = (body) memory = (memory)"
    }
  static func builder() -> Builder {
    return Builder()
  }
  class Builder {
    let computer = Computer()
    @discardableResult
    func set(body: String) -> Builder {
      computer.body = body
      return self
    }
    @discardableResult
    func set(memory: String) -> Builder {
      computer.memory = memory
      return self
    }
    func build() -> Computer {
      return computer
    }
  }
}

现在,咱们界说了一个Computer类,这个类的创立并不由自己完结,而是由Computer内部的一个Builder类完结,有意思吧?

风海: 理解了,所以说制作者形式要求杂乱的类内部要有个Builder吗?

铜锣: 哦不不,Builder详细放在那里不是规划形式规定的,规划形式仅仅规划了个整体思维,详细完成是由开发者根据实际情况确定的。

在这个比如里,在咱们在创立Computer目标的时候,能够这么写

swift
仿制代码
let builder = Computer.builder()
builder.set(body: "Intel 天逸510S")
builder.set(memory: "DDR4")
let computer = builder.build()
print("(computer.description)")

风海: 原来如此,这时候Computer的创立被拖延了,交给Builder去逐渐构建特点,等构建成型后再直接创立Computer,这么写倒不错,可是代码行数还挺多的。

铜锣: 是的,所以你有没有看到,Builderset代码都会回来Builder呢,便是为了快捷性,事实上Computer的创立还能够这么写。

swift
仿制代码
let computer = Computer.builder()
    .set(body: "Intel 天逸510S")
    .set(memory: "DDR4")
    .build()
print("(computer.description)")

风海: 原来如此,这样确实快捷了很多。所以那个@discardableResult也是为了单纯特点设置而不打算接收回来值时不会收到编译器正告而设定的。

铜锣: 对,没错。咱们还能够进一步扩展,比方说咱们经过Builder来构建Computer,那么当Builder不断增加时,咱们也能够做一些Builder模板,比方如下代码:

swift
仿制代码
class HPComputerBuilder: Computer.Builder {
    override init() {
        super.init()
        set(body: "HP 超级芯片").set(memory: "DDR4")
    }
}

风海: 明白了,这样一来经过单独界说的Builder类,咱们能够十分快捷的直接构建定制的Computer

铜锣: 是的。当需求使用时咱们这么写:

swift
仿制代码
let hpComputer = HPComputerBuilder().build()
print("(hpComputer.description)")

风海: 嗯,咱们聊了这么多,好像连制作者形式的界说都没给呢。

铜锣: 是啊,界说留给最终嘛。

生成器形式(英:Builder Pattern)是一种规划形式,又名:制作形式,是一种目标构建形式。它能够将杂乱目标的制作过程笼统出来(笼统类别),使这个笼统过程的不同完成方法能够结构出不同体现(特点)的目标。

风海: 好了,三点几了,喝茶去了。

铜锣: 欧耶。