建造者模式概念
建造者模式的意思是通过一个或多个建造者,将各种的零件组合成一个完整的产品。并且一个完整的产品可能需要多个零件组成,并且有些零件不可或缺,零件(属性)之间可能相互依赖。拿汉堡加工来举例,制作一个汉堡,需要面包、生菜、肉类、酱汁,假如没有面包就没法制作汉堡,如果没有肉类,制作出来的东西也不能叫做汉堡,并且制作汉堡的过程也需要一定的顺序,比如要先放面包,再放生菜和肉,最后才淋上酱汁。
建造者模式通常包含以下几个角色
- 抽象构建者: 构建者的抽象接口,定义了构建产品的抽象方法
- 具体构建者: 构建者抽象的具体实现,实现了构建产品的方法
- 构建者的调度者: 用来调度构建者完成产品的构建
- 产品: 要构建的具体产品
代码示例及说明
创建一个抽象构建者,包含一个构建汉堡的抽象方法
/**
* 食品构建者抽象类
*/
public interface FootBuilder {
HamBurg buildHamburg();
}
创建两个具体构建者,实现抽象构建者
/**
* 1、普通汉堡构建者
*/
public class HamburgBuilder implements FootBuilder{
//整个汉堡
@Override
public HamBurg buildHamburg(){
HamBurg hamBurg = new HamBurg();
hamBurg.setBread().setLeaf().setMeat().setSauce().setBrand("普通");
return hamBurg;
}
}
/**
* 2、肯德基汉堡构建者
*/
public class KFCHamburgBuilder implements FootBuilder{
//整个汉堡
@Override
public HamBurg buildHamburg(){
HamBurg hamBurg = new HamBurg();
hamBurg.setBread().setLeaf().setMeat().setSauce().setBrand("肯德基");
return hamBurg;
}
}
hamBurg.setBread().setLeaf().setMeat().setSauce().setBrand执行链表示产品构建过程,执行了放面包、加生菜、加肉片、加酱汁,最终完成汉堡构建的过程。
创建普通汉堡产品类
/**
* 汉堡包
*/
public class HamBurg {
//面包
private boolean bread;
//肉
private boolean meat;
//生菜
private boolean leaf;
//酱汁
private boolean sauce;
//品牌
private String brand;
public HamBurg setBread() {
this.bread = true;
return this;
}
public HamBurg setMeat() {
if(!this.bread){
throw new RuntimeException("要先放面包片");
}
this.meat = true;
return this;
}
public HamBurg setLeaf() {
if(!this.bread){
throw new RuntimeException("要先放面包片");
}
this.leaf = true;
return this;
}
public HamBurg setSauce() {
if(!this.leaf||!meat){
throw new RuntimeException("请先放生菜或肉片后,在加酱汁");
}
this.sauce = true;
return this;
}
public void setBrand(String brand) {
this.brand = brand;
}
@Override
public String toString() {
return this.brand+"汉堡制作完成";
}
}
上面的代码定义了产品所包含的属性,就是用这些属性去模拟产品构建的过程。
创建肯德基汉堡产品类
/**
* 肯德基汉堡包
*/
public class KFCHamBurg {
//面包
private boolean bread;
//肉
private boolean meat;
//生菜
private boolean leaf;
//酱汁
private boolean sauce;
//品牌
private String brand;
public KFCHamBurg setBread() {
this.bread = true;
return this;
}
public KFCHamBurg setMeat() {
if(!this.bread){
throw new RuntimeException("要先放面包片");
}
this.meat = true;
return this;
}
public KFCHamBurg setLeaf() {
if(!this.bread){
throw new RuntimeException("要先放面包片");
}
this.leaf = true;
return this;
}
public KFCHamBurg setSauce() {
if(!this.leaf||!meat){
throw new RuntimeException("请先放生菜或肉片后,在加酱汁");
}
this.sauce = true;
return this;
}
public void setBread(String brand) {
this.bread = bread;
}
@Override
public String toString() {
return this.brand+"汉堡制作完成";
}
}
上面的代码定义了肯德基汉堡所包含的属性,就是按一定顺序调用这些属性的修改方法去模拟产品构建的过程
提示
如果一个产品是更加复杂的,并且无法使用一个类来表示,那么就应该考虑将产品的属性定义为可以包含更多属性的对象类型
创建构建者的调度者
public class HamBurgDirector {
private FootBuilder builder;
public HamBurgDirector(FootBuilder builder){
this.builder = builder;
}
public HamBurg getHamBurg(){
return builder.buildHamburg();
}
}
这个类的作用是调用具体构建者构建产品的方法,直到完成产品的构建。
提示
对于更加复杂的产品,一个产品对象往往需要组合多个对象属性来构建产品,这个时候调度者类就会显得特别重要,可能需要在调度者中,调度构建者的多个方法完成产品的构建工作
创建测试类测试
public class test {
public static void main(String[] args) {
//构建普通汉堡
FootBuilder builder = new HamburgBuilder();
HamBurgDirector director = new HamBurgDirector(builder);
HamBurg hamBurg = director.getHamBurg();
System.out.println(hamBurg);
//构建肯德基汉堡
builder = new KFCHamburgBuilder();
director = new HamBurgDirector(builder);
HamBurg kfcHamBurg = director.getHamBurg();
System.out.println(kfcHamBurg);
}
}
输出结果:
上面的代码只是构建者模式的一个简单示例,主要想表达的意思是,当需要生产的产品是由多个产品组合而成时,往往需要一个构建者去构建对象的内部零件,这个零件可以理解为一个属性或是一个对象。调度者可以理解为是一个指挥构建者构建产品的角色,调度者拿到不同构建者构建的产品,还可以再将这些产品进行组合形成一个类似于套餐组合的东西。
总结
总之通过建造者模式,可以更好的将产品的制作步骤拆分出来,分离出具体的制作过程之后, 就可以更好的控制每一步的构建细节,这种松散的设计有利于分工合作,使程序更灵活, 并且提高了代码的复用性。