一、小案例分析
1、功能需求:
现需要建房子,建房流程:挖地基、砌墙、封顶。对于不同种类的房子(高楼,别墅),流程虽然一样,但是具体功能实现不同。如何实现建房子?
2、小菜鸡的答案:
(1)定义一个抽象接口,并定义三个抽象方法(挖地基、砌墙、封顶)。
(2)对于不同种类的房子,实现该接口,并重写相关方法即可。
(3)代码实现:
package builder.pattern;
/**
* 测试类
*
*/
public class BuilderDemo {
public static void main(String[] args) {
System.out.println("建别墅流程:");
BuilderHouse villa = new Villa();
System.out.println("\n建高楼流程");
BuilderHouse highBuild = new HighBuild();
}
}
/**
* 定义一个建房子的接口,并定义其流程
*/
interface BuilderHouse {
void scoopHole(); // 挖地基
void buildWall(); // 砌墙
void topOff(); // 封顶
}
/**
* 建别墅,实现建房子的接口
*
*/
class Villa implements BuilderHouse {
/**
* 建别墅流程
*/
public Villa() {
scoopHole();
buildWall();
topOff();
}
@Override
public void scoopHole() {
System.out.println("挖10米地基");
}
@Override
public void buildWall() {
System.out.println("砌10层墙");
}
@Override
public void topOff() {
System.out.println("楼顶建个游泳池");
}
}
/**
* 建高楼流程,实现建房子的接口
*
*/
class HighBuild implements BuilderHouse {
/**
* 建高楼流程
*/
public HighBuild() {
scoopHole();
buildWall();
topOff();
}
@Override
public void scoopHole() {
System.out.println("挖30米地基");
}
@Override
public void buildWall() {
System.out.println("砌60层墙");
}
@Override
public void topOff() {
System.out.println("楼顶建个停机坪");
}
}
(4)代码分析:
容易理解并操作,但是程序的扩展性不好,且耦合性强(将产品与创建产品的过程封装在一起)。
(5)UML图

二、建造者模式
1、什么是建造者模式
又叫生成器模式,其将复杂的对象的建造过程抽象出来,并在其子类中去实现不同的建造。用户只需要去调用就行,不需要管建造的内部细节如何实现。简单的理解为,将一堆零件拼成一个整体,而零件是抽象的,并由不同的子类去实现,用户不需要管零件是如何形成的,能组装就行。
2、建造者模式的核心角色
(1)产品(Product):一个具体的产品对象。
(2)抽象建造者(Builder):定义一个接口或抽象类,内部定义生成产品各个零件的抽象方法。
(3)具体建造者(ConcreateBuilder):实现接口,并重写生成各零件的方法。
(4)组装者(Commander):按照流程拼接零件,并返回一个对象。
(5)代码实现:
package builder.pattern;
/**
* 测试类
*
*/
public class BuilderDemo {
public static void main(String[] args) {
System.out.println("建别墅流程:");
HouseBuilder villaBuilder = new VillaBuilder();
HouseCommandar villaCommandar = new HouseCommandar(villaBuilder);
System.out.println(villaCommandar.createHouse());
System.out.println("\n建高楼流程");
HouseBuilder highBuildBuilder = new HighBuildBuilder();
HouseCommandar highBuildCommandar = new HouseCommandar(highBuildBuilder);
System.out.println(highBuildCommandar.createHouse());
}
}
/**
* 产品类
*
*/
class House {
private String basis;
private String wall;
private String roof;
public String getBasis() {
return basis;
}
public void setBasis(String basis) {
this.basis = basis;
}
public String getWall() {
return wall;
}
public void setWall(String wall) {
this.wall = wall;
}
public String getRoof() {
return roof;
}
public void setRoof(String roof) {
this.roof = roof;
}
@Override
public String toString() {
return "House [basis=" + basis + ", wall=" + wall + ", roof=" + roof + "]";
}
}
/**
* 抽象建造者,内部定义生成产品各个零件的抽象方法。
*
*/
abstract class HouseBuilder {
House house = new House();
public abstract void scoopHole(); // 挖地基
public abstract void buildWall(); // 砌墙
public abstract void topOff(); // 封顶
public House getHouse() {
return house;
}
}
/**
* 具体建造者,建别墅,继承抽象类,并重写相关方法
*
*/
class VillaBuilder extends HouseBuilder {
@Override
public void scoopHole() {
house.setBasis("挖10米地基");
}
@Override
public void buildWall() {
house.setWall("砌10层墙");
}
@Override
public void topOff() {
house.setRoof("楼顶建个游泳池");
}
}
/**
* 建高楼流程,实现建房子的接口
*
*/
class HighBuildBuilder extends HouseBuilder {
@Override
public void scoopHole() {
house.setBasis("挖30米地基");
}
@Override
public void buildWall() {
house.setWall("砌60层墙");
}
@Override
public void topOff() {
house.setRoof("楼顶建个停机坪");
}
}
/**
* 组装者,控制零件组合流程,并返回一个产品对象
*/
class HouseCommandar {
private HouseBuilder houseBuilder;
/**
* 获取具体的建造者
*/
public HouseCommandar(HouseBuilder houseBuilder) {
this.houseBuilder = houseBuilder;
}
/**
* 控制建房流程,并返回一个房子实例
*
* @return 房子实例
*/
public House createHouse() {
houseBuilder.scoopHole();
houseBuilder.buildWall();
houseBuilder.topOff();
return houseBuilder.getHouse();
}
}
(6)代码分析:
相比于上例,其将控制产品流程的代码抽出来了。使产品与产品构建流程分离,从而在一定程度上解耦。当扩展代码时,只需继承HouseBuilder 并重写相关方法即可。
(7)UML图:

3、抽象工厂模式与建造者模式的区别
(1)抽象工厂模式是根据不同的工厂去创建一个对象。
(2)建造者模式是根据流程去组装一个对象。
三、JDK源码分析(StringBuilder)
1、部分源码
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence{
}
abstract class AbstractStringBuilder implements Appendable, CharSequence{
//内部定义了一系列方法,且部分方法返回值类型为AbstractStringBuilder
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
public AbstractStringBuilder deleteCharAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
System.arraycopy(value, index+1, value, index, count-index-1);
count--;
return this;
}
}
2、源码分析
AbstractStringBuilder 内部定义了一系列返回值类型为AbstractStringBuilder 的方法,这些方法可以组合起来,形成链式调用(产品构建流程),根据链式调用来组装成最后返回的对象。
即StringBuilder 是组装者与具体建造者。AbstractStringBuilder 是抽象建造者。