设计模式之——建造模式

举报
ShaderJoy 发表于 2021/12/30 01:18:33 2021/12/30
【摘要】 1.将构造复杂对象的过程和组成对象的部件解耦。就像攒电脑一样,不管什么品牌的配件,只要兼 容就可以装上;同样,一样的配件,可以有好多组装的方式。这是对降低耦合、提高可复用 性精神的一种贯彻。 来看看建造模式的组成吧。 1) 抽象建造者角色:这个角色用来规范产品对象的各个组成成分的建造。一般而言,此角 色独...
1.将构造复杂对象的过程和组成对象的部件解耦。就像攒电脑一样,不管什么品牌的配件,只要兼
容就可以装上;同样,一样的配件,可以有好多组装的方式。这是对降低耦合、提高可复用

性精神的一种贯彻。

来看看建造模式的组成吧。

1) 抽象建造者角色:这个角色用来规范产品对象的各个组成成分的建造。一般而言,此角

色独立于应用程序的业务逻辑。

2) 具体建造者角色:担任这个角色的是于应用程序紧密相关的类,它们在指导者的调用下

创建产品实例。这个角色在实现抽象建造者角色提供的方法的前提下,达到完成产品组

装,提供成品的功能。

3) 指导者角色:调用具体建造者角色以创建产品对象。指导者并没有产品类的具体知识,

真正拥有产品类的具体知识的是具体建造者对象。

4) 产品角色:建造中的复杂对象。它要包含那些定义组件的类,包括将这些组件装配成产

品的接口。

来看下这些角色组成的类图:


首先客户程序创建一个指导者对象,一个建造者角色,并将建造者角色传入指导者对象
进行配置。然后,指导者按照步骤调用建造者的方法创建产品。最后客户程序从建造者或者
指导者那里得到产品。
从建造模式的工作流程来看,建造模式将产品的组装“外部化”到了建造者角色中来。这
是和任何正规的工厂模式不一样的——产品的创建是在产品类中完成的。


  
  1. //不同的媒体形式:
  2. class Media extends ArrayList
  3. {
  4. }
  5. class Book extends Media
  6. {
  7. }
  8. class Magazine extends Media
  9. {
  10. }
  11. class WebSite extends Media
  12. {
  13. }
  14. // 进而包含不同的媒体组成元素:
  15. class MediaItem
  16. {
  17. private String s;
  18. public MediaItem(String s)
  19. {
  20. this.s = s;
  21. }
  22. public String toString()
  23. {
  24. return s;
  25. }
  26. }
  27. class Chapter extends MediaItem
  28. {
  29. public Chapter(String s)
  30. {
  31. super(s);
  32. }
  33. }
  34. class Article extends MediaItem
  35. {
  36. public Article(String s)
  37. {
  38. super(s);
  39. }
  40. }
  41. class WebItem extends MediaItem
  42. {
  43. public WebItem(String s)
  44. {
  45. super(s);
  46. }
  47. }
  48. // 抽象建造者角色,它规范了所有媒体建造的步骤:
  49. class MediaBuilder
  50. {
  51. public void buildBase()
  52. {
  53. }
  54. public void addMediaItem(MediaItem item)
  55. {
  56. }
  57. public Media getFinishedMedia()
  58. {
  59. return null;
  60. }
  61. }
  62. // 具体建造者角色
  63. class BookBuilder extends MediaBuilder
  64. {
  65. private Book b;
  66. public void buildBase()
  67. {
  68. System.out.println("Building book framework");
  69. b = new Book();
  70. }
  71. public void addMediaItem(MediaItem chapter)
  72. {
  73. System.out.println("Adding chapter " + chapter);
  74. b.add(chapter);
  75. }
  76. public Media getFinishedMedia()
  77. {
  78. return b;
  79. }
  80. }
  81. class MagazineBuilder extends MediaBuilder
  82. {
  83. private Magazine m;
  84. public void buildBase()
  85. {
  86. System.out.println("Building magazine framework");
  87. m = new Magazine();
  88. }
  89. public void addMediaItem(MediaItem article)
  90. {
  91. System.out.println("Adding article " + article);
  92. m.add(article);
  93. }
  94. public Media getFinishedMedia()
  95. {
  96. return m;
  97. }
  98. }
  99. class WebSiteBuilder extends MediaBuilder
  100. {
  101. private WebSite w;
  102. public void buildBase()
  103. {
  104. System.out.println("Building web site framework");
  105. w = new WebSite();
  106. }
  107. public void addMediaItem(MediaItem webItem)
  108. {
  109. System.out.println("Adding web item " + webItem);
  110. w.add(webItem);
  111. }
  112. public Media getFinishedMedia()
  113. {
  114. return w;
  115. }
  116. }
  117. // 指导者角色,也叫上下文
  118. class MediaDirector
  119. {
  120. private MediaBuilder mb;
  121. public MediaDirector(MediaBuilder mb)
  122. {
  123. this.mb = mb; // 具有策略模式相似特征的
  124. }
  125. public Media produceMedia(List input)
  126. {
  127. mb.buildBase();
  128. for (Iterator it = input.iterator(); it.hasNext();)
  129. mb.addMediaItem((MediaItem) it.next());
  130. return mb.getFinishedMedia();
  131. }
  132. }
  133. // 测试程序——客户程序角色
  134. public class BuildMedia extends TestCase
  135. {
  136. private List input = Arrays.asList(new MediaItem[] {
  137. new MediaItem("item1"), new MediaItem("item2"),
  138. new MediaItem("item3"), new MediaItem("item4"), });
  139. public void testBook()
  140. {
  141. MediaDirector buildBook = new MediaDirector(new BookBuilder());
  142. Media book = buildBook.produceMedia(input);
  143. String result = "book: " + book;
  144. System.out.println(result);
  145. assertEquals(result, "book: [item1, item2, item3, item4]");
  146. }
  147. public void testMagazine()
  148. {
  149. MediaDirector buildMagazine = new MediaDirector(new MagazineBuilder());
  150. Media magazine = buildMagazine.produceMedia(input);
  151. String result = "magazine: " + magazine;
  152. System.out.println(result);
  153. assertEquals(result, "magazine: [item1, item2, item3, item4]");
  154. }
  155. public void testWebSite()
  156. {
  157. MediaDirector buildWebSite = new MediaDirector(new WebSiteBuilder());
  158. Media webSite = buildWebSite.produceMedia(input);
  159. String result = "web site: " + webSite;
  160. System.out.println(result);
  161. assertEquals(result, "web site: [item1, item2, item3, item4]");
  162. }
  163. public static void main(String[] args)
  164. {
  165. junit.textui.TestRunner.run(BuildMedia.class);
  166. }
  167. }

2、应用优点
建造模式可以使得产品内部的表象独立变化。在原来的工厂方法模式中,产品内部的表
象是由产品自身来决定的;而在建造模式中则是“外部化”为由建造者来负责。这样定义一个
新的具体建造者角色就可以改变产品的内部表象,符合“开闭原则”。
建造模式使得客户不需要知道太多产品内部的细节。它将复杂对象的组建和表示方式封
装在一个具体的建造角色中,而且由指导者来协调建造者角色来得到具体的产品实例。
每一个具体建造者角色是毫无关系的。
建造模式可以对复杂产品的创建进行更加精细的控制。产品的组成是由指导者角色调用
具体建造者角色来逐步完成的,所以比起其它创建型模式能更好的反映产品的构造过程。
3、扩展
建造模式中很可能要用到组成成品的各种组件类,对于这些类的创建可以考虑使用工厂
方法或者原型模式来实现,在必要的时候也可以加上单例模式来控制类实例的产生。但是要
坚持一个大前提就是要使引入的模式给你的系统带来好处,而不是臃肿的结构。
建造模式在得到复杂产品的时候可能要引用多个不同的组件,在这一点上来看,建造模
式和抽象工厂模式是相似的。可以从以下两点来区分两者:创建模式着重于逐步将组件装配
成一个成品并向外提供成品,而抽象工厂模式着重于得到产品族中相关的多个产品对象;抽
象工厂模式的应用是受限于产品族的(具体参见《深入浅出工厂模式》),建造模式则不会。
由于建造模式和抽象工厂模式在实现功能上相似,所以两者使用的环境都比较复杂并且
需要更多的灵活性。
组合模式中的树枝构件角色(Composite)往往是由多个树叶构件角色(Leaf)组成,
因此树枝构件角色的产生可以由建造模式来担当。

文章来源: panda1234lee.blog.csdn.net,作者:panda1234lee,版权归原作者所有,如需转载,请联系作者。

原文链接:panda1234lee.blog.csdn.net/article/details/9119607

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。