1、模式的定义与特点
建造者(Builder)模式:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
建造者模式的优点:
1、各个具体的建造者相互独立,有利于系统的扩展。
2、客户端不必知道产品内部组成的细节,便于控制细节风险。
建造者模式的缺点:
1、产品的组成部分必须相同,这限制了其使用范围。
2、如果产品的内部变化复杂,该模式会增加很多的建造者类。
建造者模式与工厂模式的关注点不同:
建造者模式注重零部件的组装过程,而工厂方法模式更注重零部件的创建过程,但两者可以结合使用。
2、模式的结构
建造者模式由产品、抽象建造者、具体建造者、指挥者等 4 个要素构成。
1、产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个部件。
2、抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法getResult()。
3、具体建造者(Concrete Builder):实现Builder接口,完成复杂产品的各个部件的具体创建方法。
4、指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
其结构图如图1 -1所示
3、模式的应用场景
建造者模式创建的是复杂对象,其产品的各个部分经常面临着剧烈的变化,但将它们组合在一起的算法却相对稳定,所以它通常在以下场合使用:
1、创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的。
2、创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的。
4、模式的扩展
建造者模式在应用过程中可以根据需要改变,如果创建的产品种类只有一种,只需要一个具体建造者,这时可以省略掉抽象建造者,甚至可以省略掉指挥者角色。
5、模式的实现
产品角色Person.java
package com.example.designpattern.builder;
/**
* @author Administrator
* @date 2020/7/6
* 产品类角色
*/
public class Person {
private String head;
private String body;
private String feet;
public Person(String head, String body, String feet) {
super();
this.head = head;
this.body = body;
this.feet = feet;
}
public Person() {
super();
}
public String getHead() {
return head;
}
public void setHead(String head) {
this.head = head;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getFeet() {
return feet;
}
public void setFeet(String feet) {
this.feet = feet;
}
@Override
public String toString() {
return "Person{" +
"head='" + head + '\'' +
", body='" + body + '\'' +
", feet='" + feet + '\'' +
'}';
}
}
抽象建造者角色Buidler.java
package com.example.designpattern.builder;
/**
* @author Administrator
* @date 2020/7/6
* 抽象建造者角色
* 负责定制创建产品表象/部件的方法
*/
public interface Buidler {
public void buildHead();
public void buildBody();
public void buildFeet();
public Person getResult();
}
具体建造者角色ManBuilder.java
package com.example.designpattern.builder;
/**
* @author Administrator
* @date 2020/7/6
* 男人的具体建造者角色
* 负责创建男人的各个部件
* <p>
* 注意:身体各部件的创建顺序无法控制
*/
class ManBuilder implements Buidler {
Person person;
public ManBuilder() {
this.person = new Person();
}
@Override
public void buildHead() {
person.setHead("男人的头部");
}
@Override
public void buildBody() {
person.setBody("男人的身体");
}
@Override
public void buildFeet() {
person.setFeet("男人的脚");
}
@Override
public Person getResult() {
return person;
}
}
具体建造者角色WomanBuilder.java
package com.example.designpattern.builder;
/**
* @author Administrator
* @date 2020/7/6
* 女人的具体建造者角色
* 负责创建女人的各个部件
* <p>
* 注意:身体各部件的创建顺序无法控制
*/
class WomanBuilder implements Buidler {
Person person;
public WomanBuilder() {
this.person = new Person();
}
@Override
public void buildHead() {
person.setHead("女人的头部");
}
@Override
public void buildBody() {
person.setBody("女人的身体");
}
@Override
public void buildFeet() {
person.setFeet("女人的脚");
}
@Override
public Person getResult() {
return person;
}
}
指导者角色Director.java
package com.example.designpattern.builder;
/**
* @author Administrator
* @date 2020/7/6
* 指导者角色
* 负责调用具体的建造者,创建产品
* 客户端直接调用
*/
class Director {
private Buidler buidler;
public Director(Buidler buidler) {
this.buidler = buidler;
}
/**
* 构造产品的方法
* 此处可以指定产品的构造顺序,如指定顺序为身体、头、脚
*/
public Person construct() {
buidler.buildBody();
buidler.buildHead();
buidler.buildFeet();
return buidler.getResult();
}
}
客户端调用Client.java
package com.example.designpattern.builder;
/**
* @author Administrator
* @date 2020/7/6
*/
class Client {
public static void main(String[] args) {
// 男人
Director director = new Director(new ManBuilder());
Person man = director.construct();
System.out.println(man);
// 女人
Director director2 = new Director(new WomanBuilder());
Person woman = director2.construct();
System.out.println(woman);
}
}
测试结果:
6、PPT素材
微信公众号: TechU