【设计模式】Builder模式

定义

Separate the construction of a complex object from its representation so that the same construction process can create different representations.

将复杂对象的创建过程与该对象的表示分离开来,以便让同一个创建过程可以创建出不同的表示。

类图



 

角色

  1. Builder:
    定义一个抽象接口,用于创建Product组成部分
  2. ConcreteBuilder:
    构建并组装Product组成部分;
    定义并跟踪所创建的表示(Product?);
    提供接口,用于查询product。
  3. Director:
    使用Builder接口构建对象
  4. Product:
    表示所创建的复杂对象;——ConcreteBuilder构建product的内部表示并定义它的组装过程;
    包含定义组成部分的类。

 

示例代码

  • Product

public class MyFile {
  private FileHead fhead;
  private FileContent fcontent;
  private FileEnd fend;
   
  public FileContent getFcontent() {
    return fcontent;
  }
  public void setFcontent(FileContent fcontent) {
    this.fcontent = fcontent;
  }
  public FileEnd getFend() {
    return fend;
  }
  public void setFend(FileEnd fend) {
    this.fend = fend;
  }
  public FileHead getFhead() {
    return fhead;
  }
  public void setFhead(FileHead fhead) {
    this.fhead = fhead;
  }
  public void write(String path) throws IOException{
    File f=new File(path);
    FileWriter fw=new FileWriter(f);
    PrintWriter out=new PrintWriter(fw);
    out.println(fhead.getValue());
    out.println(fcontent.getValue());
    out.println(fend.getValue());
    out.close();   
  }
}
 
Product Part
 
public class FileHead {
  private String value;
  public String getValue() {
    return value;
  }
  public void setValue(String value) {
    this.value = value;
  }
}
 
public class FileContent{
  private String value;
  ...
}
 
public class FileEnd {
  private String value;
  ...
}
  • Builder

public interface FileBuilder {
  void buildHead();
  void buildContent();
  void buildEnd();
  MyFile getResult();
}
  • ConcreteBuilder

public class TxtBuilder implements FileBuilder{
  private FileHead fh=new FileHead();
  private FileContent fc=new FileContent();;
  private FileEnd fe=new FileEnd();
  public void buildHead() {
    fh.setValue("This is text file");
  }
  public void buildContent() {
    fc.setValue("this is my content");
  }
  public void buildEnd() {
    fe.setValue("this is the end of the file");
  }
  public MyFile getResult() {
    MyFile my=new MyFile();
    my.setFcontent(fc);
    my.setFhead(fh);
    my.setFend(fe);
    return my;
  }
}
 
 
public class XmlBuilder implements FileBuilder {
      private FileHead fh=new FileHead();
      private FileContent fc=new FileContent();
      private FileEnd fe=new FileEnd();
     
  public void buildHead() {
    fh.setValue("<?xml version=\"1.0\" encoding=\"GB2312\"?><content>"); 
  }
  public void buildContent() {
    fc.setValue("<test>asdasd</test>");
  }
  public void buildEnd() {
    fe.setValue("</content>");   
  }
  //组装product
  public MyFile getResult() {
    MyFile my=new MyFile();
    my.setFcontent(fc);
    my.setFhead(fh);
    my.setFend(fe);
    return my;
  }
}
  • Director


public class FileDirector {
      private FileBuilder filebuilder;
      public FileDirector(FileBuilder filebuilder){
        this.filebuilder=filebuilder;
      }
 
      //一步一步创建product
      public void construct(){
        filebuilder.buildHead();
        filebuilder.buildContent();
        filebuilder.buildEnd();
      }
}
  • Client

public class Demo {
  public static void main(String[] args) throws IOException {
              //TxtBuilder
              FileBuilder fb=new TxtBuilder();
              FileDirector fd=new FileDirector(fb);             
              fd.construct();
              MyFile my = fb.getResult();
              my.write("D:/test.txt");
             
              //XmlBuilder --改变builder,就改变了product的内部表示
              FileBuilder fbxml=new XmlBuilder();
              FileDirector fdxml=new FileDirector(fbxml);
              fdxml.construct();
              MyFile myxml=fbxml.getResult();
              myxml.write("D:/test1.xml");
  }
}

 

优点

  1. 允许改变product的内部表示,定义一个新的builder即可。因为builder隐藏了product的表示和内部结构,也隐藏了product是如何组装的。
  2. 将构建和表示的代码分离开。将复杂对象的创建和表示封装起来,提供了模块化特性。每个ConcreteBuilder都定义了完整的创建和组装product的方法,不同的Director可以重用这些方法来构造不同的product。——也就是说可以替换Director,以便生成不同的product。
  3. 能更好地控制构建过程。并非一蹴而就地构建出product,而是在director的控制下一步一步地构建product。

缺点

 

适用场景

  1. 复杂对象的创建逻辑、其组成部分的创建逻辑、组装逻辑,互相独立。
  2. 构建过程允许对象有不同的表示。

诀窍

  • AbstractBuilder中的方法留空,而不定义成抽象方法。
这样ConcreteBuilder就能按需实现方法,而不是实现所有方法。
  • 为什么没有AbstractProduct?

一般ConcreteBuilder构建的product表示的差异很大。客户端会给director配置某个具体的ConcreteBuilder,所以客户端也就知道了会创建那种product。

  • 为何不把builder中的逻辑移到Product中:
让Product尽可能小,易于理解和修改;
逻辑分开后,可以定义多种builder,实现不同的逻辑

 

Related Patterns

  • Abstract Factory也是用来创建复杂对象,但是它着重于创建产品族;Builder则着重于一步一步地创建复杂对象。Builder是在最后一步返回product;而Abstract Factory立即返回product。
  • Builder通常用来构建Composite

 

高性能MySQL实战课

05-21
限时福利1:原价 129 元,最后2天仅需 69 元!后天涨价至98元 限时福利2:购课进答疑群专享柳峰(刘运强)老师答疑服务 限时福利3:购课添加助教领取价值 800 元的编程大礼包 为什么需要掌握高性能的MySQL实战? 由于互联网产品用户量大、高并发请求场景多,因此对MySQL的性能、可用性、扩展性都提出了很高的要求。使用MySQL解决大量数据以及高并发请求已经是程序员的必备技能,也是衡量一个程序员能力和薪资的标准之一。 为了让大家快速系统了解高性能MySQL核心知识全貌,我为你总结了「高性能 MySQL 知识框架图」,帮你梳理学习重点,建议收藏! 【课程设计】 课程分为四大篇章,将为你建立完整的 MySQL 知识体系,同时将重点讲解 MySQL 底层运行原理、数据库的性能调优、高并发、海量业务处理、面试解析等。 一、性能优化篇: 主要包括经典 MySQL 问题剖析、索引底层原理和事务与锁机制。通过深入理解 MySQL 的索引结构 B+Tree ,学员能够从根本上弄懂为什么有些 SQL 走索引、有些不走索引,从而彻底掌握索引的使用和优化技巧,能够避开很多实战中遇到的“坑”。 二、MySQL 8.0新特性篇: 主要包括窗口函数和通用表表达式。企业中的许多报表统计需求,如果不采用窗口函数,用普通的 SQL 语句是很难实现的。 三、高性能架构篇: 主要包括主从复制和读写分离。在企业的生产环境中,很少采用单台MySQL节点的情况,因为一旦单个节点发生故障,整个系统都不可用,后果往往不堪设想,因此掌握高可用架构的实现是非常有必要的。 四、面试篇: 程序员获得工作的第一步,就是高效的准备面试,面试篇主要从知识点回顾总结的角度出发,结合程序员面试高频MySQL问题精讲精练,帮助程序员吊打面试官,获得心仪的工作机会。

专为程序员设计的数学课

11-11
<p> 限时福利限时福利,<span>15000+程序员的选择!</span> </p> <p> 购课后添加学习助手(微信号:csdn590),按提示消息领取编程大礼包!并获取讲师答疑服务! </p> <p> <br> </p> <p> 套餐中一共包含5门程序员必学的数学课程(共47讲) </p> <p> 课程1:《零基础入门微积分》 </p> <p> 课程2:《数理统计与概率论》 </p> <p> 课程3:《代码学习线性代数》 </p> <p> 课程4:《数据处理的最优化》 </p> <p> 课程5:《马尔可夫随机过程》 </p> <p> <br> </p> <p> 哪些人适合学习这门课程? </p> <p> 1)大学生,平时只学习了数学理论,并未接触如何应用数学解决编程问题; </p> <p> 2)对算法、数据结构掌握程度薄弱的人,数学可以让你更好的理解算法、数据结构原理及应用; </p> <p> 3)看不懂大牛代码设计思想的人,因为所有的程序设计底层逻辑都是数学; </p> <p> 4)想学习新技术,如:人工智能、机器学习、深度学习等,这门课程是你的必修课程; </p> <p> 5)想修炼更好的编程内功,在遇到问题时可以灵活的应用数学思维解决问题。 </p> <p> <br> </p> <p> 在这门「专为程序员设计的数学课」系列课中,我们保证你能收获到这些:<br> <br> <span> </span> </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">①价值300元编程课程大礼包</span> </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">②应用数学优化代码的实操方法</span> </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">③数学理论在编程实战中的应用</span> </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">④程序员必学的5大数学知识</span> </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">⑤人工智能领域必修数学课</span> </p> <p> <br> 备注:此课程只讲程序员所需要的数学,即使你数学基础薄弱,也能听懂,只需要初中的数学知识就足矣。<br> <br> 如何听课? </p> <p> 1、登录CSDN学院 APP 在我的课程中进行学习; </p> <p> 2、登录CSDN学院官网。 </p> <p> <br> </p> <p> 购课后如何领取免费赠送的编程大礼包和加入答疑群? </p> <p> 购课后,添加助教微信:<span> csdn590</span>,按提示领取编程大礼包,或观看付费视频的第一节内容扫码进群答疑交流! </p> <p> <img src="https://img-bss.csdn.net/201912251155398753.jpg" alt=""> </p>
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值