建造者模式
一、定义
建造者模式(Builder):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
二、模式解读:
类图
2.2.模式中的角色
-
产品(Product):表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
-
建造者(Builder):为创建一个产品对象的各个部件指定抽象接口。
-
具体建造者(ConcreteBuilder):实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。
-
指挥者(Director):指挥并构造一个使用Builder接口的对象。
三、实例:
创建两种车:普通车和赛车,他们都是装配车轮、发动机、车身,只不过选用的部件不同。
1.具体的产品类,即我们要制造的产品汽车
- import java.util.ArrayList;
- class Car {
- private ArrayList<String> parts = new ArrayList<String>();
- public void add(String part) {
- parts.add(part);
- }
- public void show() {
- System.out.println("汽车有以下几部分构成:");
- for (String s : parts) {
- System.out.println(s);
- }
- }
- }
2.建造产品的抽象类,定义了怎么建造这个产品的方法和产生出来的结果,但是不负责具体建造
- interface Builder {
- public void buildWheel();//装配汽车车轮
- public void buildEngine();//装配汽车发动机
- public void buildBody();//装配汽车车身
- //返回最后装配好的汽车
- //汽车的组装过程不在这里进行,而是转移到下面的Director类别中进行。从而实现了解耦过程和部件
- public Car getCar();
- }
3.具体建造类,实现抽象类的所有方法,按照抽象的设计来完成产品的建造和出厂过程,但是可以根据不同的客户需求选用不同的配件,制造出同一类产品,实现产品制造这个过程。
普通车的建造
- class ConcreteBuilder1 implements Builder {
- private Car car;
- public ConcreteBuilder() {
- this.car = new Car();
- }
- public void buildWheel() {
- car.add("普通车车轮部分");
- }
- public void buildEngine() {
- car.add("普通车发动机部分");
- }
- public void buildBody() {
- car.add("普通车车身部分");
- }
- public Car getCar() {
- return car;
- }
- }
赛车的建造
- class ConcreteBuilder2 implements Builder {
- private Car car;
- public ConcreteBuilder() {
- this.car = new Car();
- }
- public void buildWheel() {
- car.add("赛车车轮部分");
- }
- public void buildEngine() {
- car.add("赛车发动机部分");
- }
- public void buildBody() {
- car.add("赛车车身部分");
- }
- public Car getCar() {
- return car;
- }
- }
4.有了产品规格,制造流程图,制造车间,还缺一个负责调度的家伙,他来操作制造的机器,但是结果是具体的机器吐出来的产品,所以这个家伙只管闭着眼睛造就行了。
- class Director {
- public void Construct(Builder builder) {
- builder.buildWheel();
- builder.buildEngine();
- builder.buildBody();
- }
- }
5.客户端调用,开始造吧
- public class Client {
- public static void main(String[] args) {
- Director designer = new Director();
- Builder builder = new ConcreteBuilder1();
- designer.Construct(builder);
- Car car = builder.getCar();
- car.show();
- }
- }
如果你在构造一个复杂的东西(对象)的时候,最好把调度者,建造蓝图,产品,建造机器都分开来,这像一个制造流程。
四. 模式总结
4.1 优点
-
用户只需要指定要建造的类型就可以得到它们,而具体的建造过程和细节不需要知道。
-
建造代码与表示相分离,如果要改变一个产品的内部表示,只要再定义一个新的具体的建造者就可以了。
-
建造过程由指挥者来控制,建造细节由一个抽象类来控制,对于实现建造细节的具体类来说,不会遗漏某一个步骤。
4.2 缺点
以上例子说明,现在我要增加产品的一个细节,如把创建方向盘的过程也添加进来,看我们需要改哪些类。
4.3 实用范围
-
当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
-
当复杂对象的部件相对稳定,不会发生变化时
-
当构造过程必须允许被构造的对象有不同的表示时。