建造模式

建造模式属于对象创建型模式,建造模式的目的为将复杂对象的构建过程与其部件实现方式分离,使得同样的构建过程可以有不同的表示,同时相同的构建过程也能够适用于不同的部件实现方式。

建造模式的适用性

建造模式主要适用于以下情况:

  • 当需要复杂对象的创建方法应该独立于该对象的组成部分的构造方法时。
  • 当构造算法必须能够接受被构造的对象使用相同的构造算法有不同的对象表示时。

建造模式的具体实现结构

在上述结构图中,我们可以看到建造模式总共有4个角色:

1、Builder(抽象建造者)角色:抽象建造者为创建Product对象的各个组成部分提供接口。

2、ConcreteBuilder(具体建造者)角色:具体建造者角色通过实现抽象建造者的每个BuildPart方法,并且在对象建造完成后返回结果实例。每一个具体建造者都负责一类产品对象的各个组成部分的建造方法,每一个具体建造者的方法只需要写一次,多个不同的Director(导向器)角色都可以调用生成同一类型下不同的产品。

3、Director(导向器)角色:通过复杂的算法调用具体建造者的方法建造出相应的产品对象。需要说的是同一个导向器实例可以调用不同具体建造者实例的方法构建出不同的产品对象,其中不同具体建造者的方法不能组合使用来构建对象。

4、Procdute(产品)角色:建造模式产生的复杂对象就是产品角色。一个建造模式中可能会有很多个不同类型的产品,每个产品实现的接口都不相同,所以产品角色没有必要抽象出通用的接口。

建造模式的应用

  我们平时画一个人要画他的头、手、身体、脚,这些是一个人的组成部分,固定需要画的。我们可以抽象出一个画头、手、身体、脚的接口出来,具体怎么画人可以再通过抽象出来的接口来定。比如说:普通一点的就是一个头、一个身体、两只手、两只脚,但是也可以画出一个人有三头六臂得人等等。下面我们定义一个抽象方法给出实现一个人身上的各个部件:

  1. public abstract class PersonBuilder {
  2. public abstract void buileHead();
  3.  
  4. public abstract void buildLeftHand();
  5.  
  6. public abstract void buildRightHand();
  7.  
  8. public abstract void buledBody();
  9.  
  10. public abstract void buileLeftLeg();
  11.  
  12. public abstract void buileRightLeg();
  13.  
  14. public abstract Person getResult();
  15.  
  16. }

下面定义一个构造人类的类继承抽象类PersonBuilder,分别实现头、身体、手、大腿这些部件的构建。

  1. public class HumanBuilder extends PersonBuilder {
  2.  
  3. Person person =new Person();
  4. @Override
  5. public void buileHead() {
  6. System.out.println("画一个人类的头");
  7. person.setHead("人类的头");
  8. }
  9.  
  10. @Override
  11. public void buildLeftHand() {
  12. System.out.println("画一个人类的左手");
  13. person.setLeftHand("人类的左手");
  14. }
  15.  
  16. @Override
  17. public void buildRightHand() {
  18. System.out.println("画一个人类的右手");
  19. person.setRightHand("人类的右手");
  20. }
  21.  
  22. @Override
  23. public void buledBody() {
  24. System.out.println("画一个人类的身体");
  25. person.setBody("人类的身体");
  26. }
  27.  
  28. @Override
  29. public void buileLeftLeg() {
  30. System.out.println("画一个人类的左腿");
  31. person.setLeftLeg("人类的左腿");
  32. }
  33.  
  34. @Override
  35. public void buileRightLeg() {
  36. System.out.println("画一个人类的右腿");
  37. person.setRightLeg("人类的右腿");
  38. }
  39. @Override
  40. public Person getResult(){
  41. return person;
  42. }
  43. }

产品类Person

  1. public class Person {
  2.  
  3. private String Head;
  4. private String LeftHand;
  5. private String RightHand;
  6. private String Body;
  7. private String LeftLeg;
  8. private String RightLeg;
  9.  
  10. public String getHead() {
  11. return Head;
  12. }
  13.  
  14. public void setHead(String head) {
  15. Head = head;
  16. }
  17.  
  18. public String getLeftHand() {
  19. return LeftHand;
  20. }
  21.  
  22. public void setLeftHand(String leftHand) {
  23. LeftHand = leftHand;
  24. }
  25.  
  26. public String getRightHand() {
  27. return RightHand;
  28. }
  29.  
  30. public void setRightHand(String rightHand) {
  31. RightHand = rightHand;
  32. }
  33.  
  34. public String getBody() {
  35. return Body;
  36. }
  37.  
  38. public void setBody(String body) {
  39. Body = body;
  40. }
  41.  
  42. public String getLeftLeg() {
  43. return LeftLeg;
  44. }
  45.  
  46. public void setLeftLeg(String leftLeg) {
  47. LeftLeg = leftLeg;
  48. }
  49.  
  50. public String getRightLeg() {
  51. return RightLeg;
  52. }
  53.  
  54. public void setRightLeg(String rightLeg) {
  55. RightLeg = rightLeg;
  56. }
  57. }

  最后通过一个PersonDirector引导器来完成一个人的组装构建,通过调用HumanBuilder的方法通过不同的算法可以组建一个有一个头、两个手、一个身体、两只脚的正常人,也可以构建出一个拥有三头六臂的神人,还可以构建出一位只有一只手的残疾人,这就是我们所说的通过不同的构建方法调用同一个建造器可以得到不同的表示。同样的道理还可以再定义一个外星人的AlienBuilder建造器,通过组装个头、两个手、一个身体、两只脚的人类的组装方法得到与人类完全不同的外星人对象。

  所以说不同的构造方法可以得到复杂对象的不同表示,相同的构造方法也可以创造出不同的对象的表示。

  下面给出一种组装一个头、两个手、一个身体、两只脚的正常人的构造方法。

  1. public class PersonDirector {
  2. private PersonBuilder personBuilder;
  3.  
  4. public PersonDirector(PersonBuilder personBuilder) {
  5. this.personBuilder = personBuilder;
  6. }
  7.  
  8. public void CreatePerson() {
  9. personBuilder.buileHead();
  10. personBuilder.buildLeftHand();
  11. personBuilder.buildRightHand();
  12. personBuilder.buledBody();
  13. personBuilder.buileLeftLeg();
  14. personBuilder.buileRightLeg();
  15. }
  16. }

Clien调用

  1. public class Client {
  2. public static void main(String[] args) {
  3. PersonBuilder personBuilder = new HumanBuilder();
  4. PersonDirector personDirector = new PersonDirector(personBuilder);
  5. personDirector.CreatePerson();
  6. Person person = personBuilder.getResult()
  7. }
  8. }
  1. 画一个人类的头
  2. 画一个人类的左手
  3. 画一个人类的右手
  4. 画一个人类的身体
  5. 画一个人类的左腿
  6. 画一个人类的右腿

总结

  建造模式可以很轻易的就改变一个产品的内部表示,通过定义一个新的生成器在客户端就可以调用不同的生成器产生不同的对象表示;同时建造模式也将产品的构建过程和表示分离开,使得客户不用知道一个产品的内部构造是什么样的,只需要调用生成器的接口就可以建造出一个需要的对象;最后建造模式可以使得使用者能够对产品的构建过程进行更加精确的控制,通过导向器一一步一步的建造出一个复杂的对象。

  建造模式和抽象工厂模式的区别在于建造模式更加注重的是一步一步构建产品的过程,而抽象工厂模式更加注重一系列相关联的产品部件组建出一个产品。建造模式是一步一步的构建产品,而抽象工厂模式是立即就生成对象。

java设计模式--建造模式的更多相关文章

  1. 3.java设计模式-建造者模式

    Java设计模式-建造者模式 在<JAVA与模式>一书中开头是这样描述建造(Builder)模式的: 建造模式是对象的创建模式.建造模式可以将一个产品的内部表象(internal repr ...

  2. Java设计模式——组合模式

    JAVA 设计模式 组合模式 用途 组合模式 (Component) 将对象组合成树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有唯一性. 组合模式是一种结构型模 ...

  3. linkin大话设计模式--建造模式

    linkin大话设计模式--建造模式 建造模式是对象的创建模式,可以讲一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象. 建造模式的结构: 抽象建造者 ...

  4. java设计模式--单列模式

    java设计模式--单列模式 单列模式定义:确保一个类只有一个实例,并提供一个全局访问点. 下面是几种实现单列模式的Demo,每个Demo都有自己的优缺点: Demo1: /** * 单列模式需要满足 ...

  5. Java设计模式-代理模式之动态代理(附源代码分析)

    Java设计模式-代理模式之动态代理(附源代码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的差别就是:动态代理是在执行时刻动态的创建出代理类及其对象. 上篇中的静态代 ...

  6. Java设计模式——外观模式

    JAVA 设计模式 外观模式 用途 外观模式 (Facade) 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外观模式是一种结构型模式. 结构

  7. 【设计模式】Java设计模式 -工厂模式

    [设计模式]Java设计模式 -工厂模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目 ...

  8. 【设计模式】Java设计模式 - 原型模式

    [设计模式]Java设计模式 - 原型模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起 ...

  9. 【设计模式】Java设计模式 - 桥接模式

    [设计模式]Java设计模式 - 桥接模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起 ...

随机推荐

  1. POJ3728 THE MERCHANT LCA RMQ DP

    题意简述:给定一个N个节点的树,1<=N<=50000 每个节点都有一个权值,代表商品在这个节点的价格.商人从某个节点a移动到节点b,且只能购买并出售一次商品,问最多可以产生多大的利润. ...

  2. python-pycharm 设置默认代码及注释

    pycharm

  3. 配置android-studio应用的快捷键

    http://blog.sina.com.cn/s/blog_ad64b8200102vnl4.html

  4. bzoj2962

    线段树+卷积 这个东西直接算不太好,但是合并两段结果却很方便,假设c[i]表示选i个数乘积的和,那么$a[i]=\sum_{j=0}^{i}{b[j]*c[i-j]}$ 线段树维护即可 #includ ...

  5. $bzoj4569$

    $st表+并查集$ $考虑暴力方法:我们每次将对应相等的位置用并查集连起来,那么最终答案就是9*10^{连通块个数-1}$ $很明显上面这个办法过不去,问题在于重复次数太多了,如果一个区间已经对应相等 ...

  6. sqlserver:rank() over()函数

    先前在oracle数据库中接触过over()函数的一系列使用,但是在实际的sql开发中并没有太多的使用,这次在sqlserver的sql拼写中重新遇到这个函数,故结合网上的例子和项目中实际中使用,将其 ...

  7. 爬虫库之BeautifulSoup学习(五)

    css选择器: 我们在写 CSS 时,标签名不加任何修饰,类名前加点,id名前加 #,在这里我们也可以利用类似的方法来筛选元素,用到的方法是 soup.select(),返回类型是 list 1)通过 ...

  8. CF-796B

    B. Find The Bone time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  9. 02-安装JDK - Java快速入门

    jdk安装的版本

  10. OGNL和类型转换

    转载 JavaWeb -- Struts 数据传输:OGNL和类型转换 1. 数据传输:OGNL和类型转换 OGNL和struts2 OGNL:Object-Graph Navigation Lang ...