一. 概述
建造者模式(Builder)
,又叫生成器模式,它将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式可以将一个产品的内部表象与产品的生成过程分割开来,使用建造者模式,用户就只需指定需要建造的类型就可以得到它们,二具体建造的过程和细节就不需要知道了。
建造者模式相比于工厂模式更加关注组成部分的装配细节和顺序。
创建者模式属于创建型模式。
二. UML类图解析
建造者模式的UML类图如下:
- Builder:为创建一个Product对象的各个部件指定的抽象接口,buildPart()是对象组成部分构造的抽象方法,根据需求可以有多个组成部分的构造方法。
- ConcreteBuilder:具体建造者,继承自Builder,构造和装配各个部件,getResult()返回构造后的实例。
- Director:指挥者,持有一个Builder引用,调用具体的创建者的各个部件来创建对象,负责保证对象各部分完整创建或者按某种顺序创建 。
- Product:产品,要创建的具体对象,一般来说是一个复杂的对象,包含多个组成部分。
三. 代码实现
这里把电脑作为一个产品,一般来说一个可以使用的台式电脑包括显示器、主机、键盘和鼠标,各个组成部分可以有不同的品牌、性能、型号等细节,下面就使用建造者模式来对电脑进行实现。
产品类——Computer
1 | package io.github.brightloong.design.builder; |
构建抽象——ComputerBuilder
1 | package io.github.brightloong.design.builder; |
具体构建类——SuperComputerBuilder
1 | package io.github.brightloong.design.builder; |
指挥者——ComputerDirector
1 | package io.github.brightloong.design.builder; |
客户端调用和输出
1 | package io.github.brightloong.design.builder; |
输出:
1 | Computer{displayer='37.5英寸显示器IPS曲面屏微边框防眩光4K屏幕', host='i7-6950X/TiTANX 高端硬管水冷电脑六核游戏主机', keyboard='猛禽竞技机械键盘', mouse='逆天悬浮鼠标'} |
四. 总结
使用场景
- 用于创建一些复杂的对象,这些对象内部构建的顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。
- 当创建复杂的对象的算法应该独立于该对象的组成部分已经它们的装配方法时。
优点
- 建造者模式使得建造代码与表示代码分离,隐藏了产品实现细节。
- 如果要改变一个产品的内部表示,只要再定义一个具体的建造者就可以了,方便扩展。
- 建造者模式通过指挥者可以控制组件建造顺序,能实现一定程度的细节把控,特别是那种生成的产品对象之间存在属性依赖的情况。
缺点
- 如果产品多变,会生成大量的建造类,造成类膨胀。
五. 扩展——构建器
在《Effective Java》一书中,第2条提到:
遇到多个构造器参数时要考虑用构建器。
当有多个参数的时候,客户端代码不仅难编写,也很难阅读,再有,客户端可能不清楚每个参数到底代表什么。
这里也使用到了Builder模式,不直接生成想要的对象,二是让客户端利用所有必要的参数调用Builder构造器,得到一个builder对象。然后客户端在builder对象上调用类似于setter的方法,来设置每个相关的可选参数。最后,客户端调用无参的build方法来生成不可变(相比较JavaBeans模式,也就是调用set方法来进行设值,这种方式可以生成不可变对象)的对象。下面的是具体的代码,来自《Effective Java》书上的列子。
1 | package io.github.brightloong.design.builder; |
调用和输出:
1 | package io.github.brightloong.design.builder; |
输出:
1 | NutritionFacts{servingSize=240, servings=8, calories=100, fat=0, sodium=35, carbohydrate=27} |