创建模式 -- 建造者模式
一、小案例分析
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 是抽象建造者。