经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
创建模式 -- 建造者模式
来源:cnblogs  作者:累成一条狗  时间:2019/8/16 9:37:24  对本文有异议

一、小案例分析

1、功能需求:

  现需要建房子,建房流程:挖地基、砌墙、封顶。对于不同种类的房子(高楼,别墅),流程虽然一样,但是具体功能实现不同。如何实现建房子?

2、小菜鸡的答案:

(1)定义一个抽象接口,并定义三个抽象方法(挖地基、砌墙、封顶)。
(2)对于不同种类的房子,实现该接口,并重写相关方法即可。
(3)代码实现:

  1. package builder.pattern;
  2. /**
  3. * 测试类
  4. *
  5. */
  6. public class BuilderDemo {
  7. public static void main(String[] args) {
  8. System.out.println("建别墅流程:");
  9. BuilderHouse villa = new Villa();
  10. System.out.println("\n建高楼流程");
  11. BuilderHouse highBuild = new HighBuild();
  12. }
  13. }
  14. /**
  15. * 定义一个建房子的接口,并定义其流程
  16. */
  17. interface BuilderHouse {
  18. void scoopHole(); // 挖地基
  19.  
  20. void buildWall(); // 砌墙
  21.  
  22. void topOff(); // 封顶
  23. }
  24. /**
  25. * 建别墅,实现建房子的接口
  26. *
  27. */
  28. class Villa implements BuilderHouse {
  29. /**
  30. * 建别墅流程
  31. */
  32. public Villa() {
  33. scoopHole();
  34. buildWall();
  35. topOff();
  36. }
  37. @Override
  38. public void scoopHole() {
  39. System.out.println("挖10米地基");
  40. }
  41. @Override
  42. public void buildWall() {
  43. System.out.println("砌10层墙");
  44. }
  45. @Override
  46. public void topOff() {
  47. System.out.println("楼顶建个游泳池");
  48. }
  49. }
  50. /**
  51. * 建高楼流程,实现建房子的接口
  52. *
  53. */
  54. class HighBuild implements BuilderHouse {
  55. /**
  56. * 建高楼流程
  57. */
  58. public HighBuild() {
  59. scoopHole();
  60. buildWall();
  61. topOff();
  62. }
  63. @Override
  64. public void scoopHole() {
  65. System.out.println("挖30米地基");
  66. }
  67. @Override
  68. public void buildWall() {
  69. System.out.println("砌60层墙");
  70. }
  71. @Override
  72. public void topOff() {
  73. System.out.println("楼顶建个停机坪");
  74. }
  75. }

(4)代码分析:
  容易理解并操作,但是程序的扩展性不好,且耦合性强(将产品与创建产品的过程封装在一起)。
(5)UML图

 

二、建造者模式

1、什么是建造者模式

  又叫生成器模式,其将复杂的对象的建造过程抽象出来,并在其子类中去实现不同的建造。用户只需要去调用就行,不需要管建造的内部细节如何实现。简单的理解为,将一堆零件拼成一个整体,而零件是抽象的,并由不同的子类去实现,用户不需要管零件是如何形成的,能组装就行。

2、建造者模式的核心角色

(1)产品(Product):一个具体的产品对象。
(2)抽象建造者(Builder):定义一个接口或抽象类,内部定义生成产品各个零件的抽象方法。
(3)具体建造者(ConcreateBuilder):实现接口,并重写生成各零件的方法。
(4)组装者(Commander):按照流程拼接零件,并返回一个对象。
(5)代码实现:

  1. package builder.pattern;
  2. /**
  3. * 测试类
  4. *
  5. */
  6. public class BuilderDemo {
  7. public static void main(String[] args) {
  8. System.out.println("建别墅流程:");
  9. HouseBuilder villaBuilder = new VillaBuilder();
  10. HouseCommandar villaCommandar = new HouseCommandar(villaBuilder);
  11. System.out.println(villaCommandar.createHouse());
  12. System.out.println("\n建高楼流程");
  13. HouseBuilder highBuildBuilder = new HighBuildBuilder();
  14. HouseCommandar highBuildCommandar = new HouseCommandar(highBuildBuilder);
  15. System.out.println(highBuildCommandar.createHouse());
  16. }
  17. }
  18. /**
  19. * 产品类
  20. *
  21. */
  22. class House {
  23. private String basis;
  24. private String wall;
  25. private String roof;
  26. public String getBasis() {
  27. return basis;
  28. }
  29. public void setBasis(String basis) {
  30. this.basis = basis;
  31. }
  32. public String getWall() {
  33. return wall;
  34. }
  35. public void setWall(String wall) {
  36. this.wall = wall;
  37. }
  38. public String getRoof() {
  39. return roof;
  40. }
  41. public void setRoof(String roof) {
  42. this.roof = roof;
  43. }
  44. @Override
  45. public String toString() {
  46. return "House [basis=" + basis + ", wall=" + wall + ", roof=" + roof + "]";
  47. }
  48. }
  49. /**
  50. * 抽象建造者,内部定义生成产品各个零件的抽象方法。
  51. *
  52. */
  53. abstract class HouseBuilder {
  54. House house = new House();
  55. public abstract void scoopHole(); // 挖地基
  56.  
  57. public abstract void buildWall(); // 砌墙
  58.  
  59. public abstract void topOff(); // 封顶
  60.  
  61. public House getHouse() {
  62. return house;
  63. }
  64. }
  65. /**
  66. * 具体建造者,建别墅,继承抽象类,并重写相关方法
  67. *
  68. */
  69. class VillaBuilder extends HouseBuilder {
  70. @Override
  71. public void scoopHole() {
  72. house.setBasis("挖10米地基");
  73. }
  74. @Override
  75. public void buildWall() {
  76. house.setWall("砌10层墙");
  77. }
  78. @Override
  79. public void topOff() {
  80. house.setRoof("楼顶建个游泳池");
  81. }
  82. }
  83. /**
  84. * 建高楼流程,实现建房子的接口
  85. *
  86. */
  87. class HighBuildBuilder extends HouseBuilder {
  88. @Override
  89. public void scoopHole() {
  90. house.setBasis("挖30米地基");
  91. }
  92. @Override
  93. public void buildWall() {
  94. house.setWall("砌60层墙");
  95. }
  96. @Override
  97. public void topOff() {
  98. house.setRoof("楼顶建个停机坪");
  99. }
  100. }
  101. /**
  102. * 组装者,控制零件组合流程,并返回一个产品对象
  103. */
  104. class HouseCommandar {
  105. private HouseBuilder houseBuilder;
  106. /**
  107. * 获取具体的建造者
  108. */
  109. public HouseCommandar(HouseBuilder houseBuilder) {
  110. this.houseBuilder = houseBuilder;
  111. }
  112. /**
  113. * 控制建房流程,并返回一个房子实例
  114. *
  115. * @return 房子实例
  116. */
  117. public House createHouse() {
  118. houseBuilder.scoopHole();
  119. houseBuilder.buildWall();
  120. houseBuilder.topOff();
  121. return houseBuilder.getHouse();
  122. }
  123. }

(6)代码分析:
  相比于上例,其将控制产品流程的代码抽出来了。使产品与产品构建流程分离,从而在一定程度上解耦。当扩展代码时,只需继承HouseBuilder 并重写相关方法即可。
(7)UML图:

3、抽象工厂模式与建造者模式的区别

(1)抽象工厂模式是根据不同的工厂去创建一个对象。
(2)建造者模式是根据流程去组装一个对象。


三、JDK源码分析(StringBuilder)

1、部分源码

  1. public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence{
  2. }
  3. abstract class AbstractStringBuilder implements Appendable, CharSequence{
  4. //内部定义了一系列方法,且部分方法返回值类型为AbstractStringBuilder
  5. public AbstractStringBuilder append(String str) {
  6. if (str == null)
  7. return appendNull();
  8. int len = str.length();
  9. ensureCapacityInternal(count + len);
  10. str.getChars(0, len, value, count);
  11. count += len;
  12. return this;
  13. }
  14. public AbstractStringBuilder deleteCharAt(int index) {
  15. if ((index < 0) || (index >= count))
  16. throw new StringIndexOutOfBoundsException(index);
  17. System.arraycopy(value, index+1, value, index, count-index-1);
  18. count--;
  19. return this;
  20. }
  21. }

2、源码分析

  AbstractStringBuilder 内部定义了一系列返回值类型为AbstractStringBuilder 的方法,这些方法可以组合起来,形成链式调用(产品构建流程),根据链式调用来组装成最后返回的对象。
即StringBuilder 是组装者与具体建造者。AbstractStringBuilder 是抽象建造者。
  

原文链接:http://www.cnblogs.com/l-y-h/p/11360427.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号