建造者模式(Builder Pattern):使用多个简单的对象来一步步创建一个复杂的对象,将一个复杂的对象的构建与它的表示分离,将变与不变分离开来。
建造者一般包括产品类(javaBean)、抽象创建者(接口)、具体创建者(实现类)以及指导者四个角色。
1、产品类:待创建对象的复杂类以及可能存在的组成该复杂对象的其他类
2、抽象创建者:规范复杂对象中各个成品的创建规则,不涉及具体的创建过程
3、具体创建者:实现抽象创建者接口的实现类,在具体创建者中具体定义创建复杂对象的方式,在构建完成后,返回该复杂对象的实例
4、指导者:调用抽象创建者的引用,在具体使用时再实例化该创建者,在指导者中,不涉及具体的产品的信息,只负责保证最终复杂对象各个成分的创建以及创建的顺序
下面通过一个简单的示例来演示该设计模式的原理与实现过程(套餐饭的烹饪过程):
1、产品类:
public class SettleMeal { private String majorFood; //主食 private String repast; //下饭菜 private String drink; //喝的 public String getMajorFood() { return majorFood; } public void setMajorFood(String majorFood) { this.majorFood = majorFood; } public String getRepast() { return repast; } public void setRepast(String repast) { this.repast = repast; } public String getDrink() { return drink; } public void setDrink(String drink) { this.drink = drink; } }
2、抽象创建者
public interface IMealBuilder { IMealBuilder buildMajorFood(); //准备主食 IMealBuilder builderRepast(); //准备下饭菜 IMealBuilder builderDrink(); //准备饮料 SettleMeal produce(); //获取成品 }
3、具体创建者
public class MeatSettleMealBuilder implements IMealBuilder{ SettleMeal settleMeal; public MeatSettleMealBuilder() { settleMeal = new SettleMeal(); } @Override public MeatSettleMealBuilder buildMajorFood() { settleMeal.setMajorFood("rice"); return this; } @Override public MeatSettleMealBuilder builderRepast() { settleMeal.setRepast("meat"); return this; } @Override public MeatSettleMealBuilder builderDrink() { settleMeal.setDrink("coke"); return this; } @Override public SettleMeal produce() { return settleMeal; } }
4、指导者
public class SettleMealDirector { public static SettleMeal build(IMealBuilder mealBuilder) { return mealBuilder.buildMajorFood(). builderRepast(). builderDrink(). produce(); } }
5、测试类
public class mainTest { public static void main(String[] args){ SettleMealDirector director = new SettleMealDirector(); SettleMeal settleMeal = director.build(new MeatSettleMealBuilder()); System.out.println("majorFoot: "+settleMeal.getMajorFood()); System.out.println("repast: "+settleMeal.getRepast()); System.out.println("drink: "+settleMeal.getDrink()); } }
最终输出的结果是:
majorFoot: rice
repast: meat
drink: coke
最后我们来总结一下该设计模式的使用场景:一些基本部件不会变,而其他组合经常变化的时候,比如造车子(大致工序一直,但是不同车子组件不同)、买肯德基(组合大致相同,但是具体各种套餐组合不同,不如汉堡有很多种,饮料也有很多种)等等,这种需要生成的对象内部比较复杂的情况使用建造者模式比较合适。
java中有很多建造者设计模式的例子,比如StringBuilder(StringBuilder本身继承了AbstractStringBuilder抽象类)、StringBuffer、PrepareStatement等这些内置的对象都是使用了建造者模式。