目录
一、简介
建造者模式提供了一种创建对象最佳的方式
将一个复杂对象构建和表示分离,使得同样构建有不同的表示
大部分情况下,我们要混合使用很多设计模式
在用户不知道对象创建过程和细节的情况下直接创建出复杂的对象
建造者模式主要分如下四种类(角色):
- Product:最终的产品
- Builder: 抽象建造者类(有时会用接口代替)
Builder定义了构建Product的抽象步骤和返回最终产品的getProduct方法 - ConcreteBuilder: Builder的继承/实现类,实现了Product中的抽象步骤
- Director: 决定了如何创建最终产品的步骤,通过builder方法设置builder完成步骤,并通过builder的getProduct方法返回最终的产品
二、例子:造房子(指挥者和工作者)
1.创建所需产品
//产品:房子
public class Product {
private String buildA;
private String buildB;
private String buildC;
private String buildD;
public String getBuildA() {
return buildA;
}
public void setBuildA(String buildA) {
this.buildA = buildA;
}
public String getBuildB() {
return buildB;
}
public void setBuildB(String buildB) {
this.buildB = buildB;
}
public String getBuildC() {
return buildC;
}
public void setBuildC(String buildC) {
this.buildC = buildC;
}
public String getBuildD() {
return buildD;
}
public void setBuildD(String buildD) {
this.buildD = buildD;
}
@Override
public String toString() {
return "Product{" +
"buildA='" + buildA + '\'' +
", buildB='" + buildB + '\'' +
", buildC='" + buildC + '\'' +
", buildD='" + buildD + '\'' +
'}';
}
}
2.创建抽象建造者类
public abstract class Builder {
abstract void buildA(); //铺地基
abstract void buildB(); //浇水泥
abstract void buildC(); //铺电线
abstract void buildD(); //粉刷墙
//得到产品
abstract Product getProduct();
}
3.创建具体工人继承建造者类
//具体的建造者——工人
public class Worker extends Builder{
private Product product;
//工人负责创建产品
public Worker(){
product = new Product();
}
@Override
void buildA() {
product.setBuildA("铺地基");
System.out.println("工人铺地基");
}
@Override
void buildB() {
product.setBuildB("浇水泥");
System.out.println("工人浇水泥");
}
@Override
void buildC() {
product.setBuildC("铺电线");
System.out.println("工人铺电线");
}
@Override
void buildD() {
product.setBuildD("粉刷墙");
System.out.println("工人粉刷墙");
}
@Override
Product getProduct() {
return product;
}
}
4.创建指挥者
//指挥:核心,负责指挥构建一个工程,工程如何构建由指挥决定
public class Director {
//指挥工人按照指定的顺序建房子
public Product build(Builder builder){
builder.buildA();
builder.buildB();
builder.buildC();
builder.buildD();
return builder.getProduct();
}
}
class Test{
public static void main(String[] args) {
//找一个指挥
Director director = new Director();
//给指挥配工人,工人完成任务,得到产品
Product product = director.build(new Worker());
//如果给不同的工人,可以获得不同的product
System.out.println(product);
}
}
三、例子:麦当劳(指挥者即工作者)
1.创建吃的套餐类
//套餐
public class Product {
//默认套餐
private String BuildA="薯条";
private String BuildB="汉堡";
private String BuildC="可乐";
private String BuildD="鸡块";
public String getBuildA() {
return BuildA;
}
public void setBuildA(String buildA) {
BuildA = buildA;
}
public String getBuildB() {
return BuildB;
}
public void setBuildB(String buildB) {
BuildB = buildB;
}
public String getBuildC() {
return BuildC;
}
public void setBuildC(String buildC) {
BuildC = buildC;
}
public String getBuildD() {
return BuildD;
}
public void setBuildD(String buildD) {
BuildD = buildD;
}
@Override
public String toString() {
return "Product{" +
"BuildA='" + BuildA + '\'' +
", BuildB='" + BuildB + '\'' +
", BuildC='" + BuildC + '\'' +
", BuildD='" + BuildD + '\'' +
'}';
}
}
2.创建抽象建造者类
//抽象建造者
public abstract class Builder {
//返回Builder为链式编程埋下伏笔
//msg为用户提供了自定义选择
abstract Builder buildA(String msg); //薯条
abstract Builder buildB(String msg); //汉堡
abstract Builder buildC(String msg); //可乐
abstract Builder buildD(String msg); //鸡块
//得到产品
abstract Product getProduct();
}
3.创建具体服务员类继承建造者类
public class Waiter extends Builder{
private Product product;
public Waiter(){
product = new Product();
}
@Override
Builder buildA(String msg) {
product.setBuildA(msg);
return this;
}
@Override
Builder buildB(String msg) {
product.setBuildB(msg);
return this;
}
@Override
Builder buildC(String msg) {
product.setBuildC(msg);
return this;
}
@Override
Builder buildD(String msg) {
product.setBuildD(msg);
return this;
}
@Override
Product getProduct() {
return product;
}
}
4.测试
public class Test {
public static void main(String[] args) {
Waiter waiter = new Waiter();
Product productA = waiter.getProduct();
//Product默认属性有:BuildA='薯条', BuildB='汉堡', BuildC='可乐', BuildD='鸡块'
System.out.println("productA"+productA);
//链式编程,服务员即指挥者,而且可以自定义传参
Product productB = waiter.buildA("全家桶").buildB("唐扬鸡块").buildC("黄焖鸡米饭").buildD("寿喜烧").getProduct();
System.out.println("productB"+productB);
}
}
四、优缺点
建造者模式的优缺点
建造者模式和抽象工厂模式的区别
单从例子很难理解设计模式,还是要在未来多敲代码看别人源码来掌握