`

builder模式2

 
阅读更多

8.2  解决方案

8.2.1  生成器模式来解决

用来解决上述问题的一个合理的解决方案就是生成器模式。那么什么是生成器模式呢?

(1)生成器模式定义

 

(2)应用生成器模式来解决的思路

       仔细分析上面的实现,构建每种格式的数据文件的处理过程,这不就是构建过程吗?而每种格式具体的步骤实现,不就相当于是不同的表示吗?因为不同的步骤实现,决定了最终的表现也就不同。也就是说,上面的问题恰好就是生成器模式要解决的问题。

要实现同样的构建过程可以创建不同的表现,那么一个自然的思路就是先把构建过程独立出来,在生成器模式中把它称为指导者,由它来指导装配过程,但是不负责每步具体的实现。当然,光有指导者是不够的,必须要有能具体实现每步的对象,在生成器模式中称这些实现对象为生成器。

       这样一来,指导者就是可以重用的构建过程,而生成器是可以被切换的具体实现。前面的实现中,每种具体的导出文件格式的实现就相当于生成器。

8.2.2  模式结构和说明

生成器模式的结构如图8.1所示。

 

图8.1  生成器模式结构示意图

Builder

       生成器接口,定义创建一个Product对象所需的各个部件的操作。

ConcreteBuilder

       具体的生成器实现,实现各个部件的创建,并负责组装Product对象的各个部件,同时还提供一个让用户获取组装完成后的产品对象的方法。

Director

       指导者,也被称为导向者,主要用来使用Builder接口,以一个统一的过程来构建所需要的Product对象。

Product

       产品,表示被生成器构建的复杂对象,包含多个部件。

8.2.3  生成器模式示例代码

(1)先看看生成器的接口定义,示例代码如下:

/**

 * 生成器接口,定义创建一个产品对象所需的各个部件的操作

 */

public interface Builder {

    /**

     * 示意方法,构建某个部件

     */

    public void buildPart();

}

(2)再看看具体的生成器实现,示例代码如下:

/**

 * 具体的生成器实现对象

 */

public class ConcreteBuilder implements Builder {

    /**

     * 生成器最终构建的产品对象

     */

    private Product resultProduct;

    /**

     * 获取生成器最终构建的产品对象

     * @return 生成器最终构建的产品对象

     */

    public Product getResult() {

       return resultProduct;

    }

 

    public void buildPart() {

       //构建某个部件的功能处理

    }

}

(3)看看相应的产品对象的接口示意,示例代码如下:

/**

 * 被构建的产品对象的接口

 */

public interface Product {

    //定义产品的操作

}

(4)再来看看指导者的实现示意,示例代码如下:

/**

 * 指导者,指导使用生成器的接口来构建产品的对象

 */

public class Director {

    /**

     * 持有当前需要使用的生成器对象

     */

    private Builder builder;

 

    /**

     * 构造方法,传入生成器对象

     * @param builder 生成器对象

     */

    public Director(Builder builder) {

       this.builder = builder;

    }

 

    /**

     * 示意方法,指导生成器构建最终的产品对象

     */

    public void construct() {

       //通过使用生成器接口来构建最终的产品对象

       builder.buildPart();

    }

}

8.2.4  使用生成器模式重写示例

       要使用生成器模式来重写示例,重要的任务就是要把指导者和生成器接口定义出来。指导者就是用来执行那四个步骤的对象,而生成器是用来实现每种格式下,对于每个步骤的具体实现的对象。

       按照生成器模式重写示例的结构如图8.2所示:

 

图8.2  生成器模式重写示例的结构示意图

下面还是一起来看看代码,会比较清楚。

(1)前面示例中的三个数据模型对象还继续沿用,这里就不去赘述了。

(2)先来看看定义的Builder接口,主要是把导出各种格式文件的处理过程的步骤定义出来,每个步骤负责构建最终导出文件的一部分。示例代码如下:

/**

 * 生成器接口,定义创建一个输出文件对象所需的各个部件的操作

 */

public interface Builder {

    /**

     * 构建输出文件的Header部分

     * @param ehm 文件头的内容

     */

    public void buildHeader(ExportHeaderModel ehm);

    /**

     * 构建输出文件的Body部分

     * @param mapData 要输出的数据的内容

     */

    public void buildBody(

Map<String,Collection<ExportDataModel>> mapData);

    /**

     * 构建输出文件的Footer部分

     * @param efm 文件尾的内容

     */

    public void buildFooter(ExportFooterModel efm);

}

(3)接下来看看具体的生成器实现,其实就是把原来示例中,写在一起的实现,分拆成多个步骤实现了,先看看导出数据到文本文件的生成器实现,示例代码如下:

/**

 * 实现导出数据到文本文件的的生成器对象

 */

public class TxtBuilder implements Builder {

    /**

     * 用来记录构建的文件的内容,相当于产品

     */

    private StringBuffer buffer = new StringBuffer();

 

    public void buildBody(

Map<String, Collection<ExportDataModel>> mapData) {

       for(String tblName : mapData.keySet()){

           //先拼接表名称

           buffer.append(tblName+"\n");

           //然后循环拼接具体数据

           for(ExportDataModel edm : mapData.get(tblName)){

              buffer.append(edm.getProductId()+","

+edm.getPrice()+","+edm.getAmount()+"\n");

           }

       }

    }

    public void buildFooter(ExportFooterModel efm) {

       buffer.append(efm.getExportUser());

    }

    public void buildHeader(ExportHeaderModel ehm) {

       buffer.append(ehm.getDepId()+","

+ehm.getExportDate()+"\n");

    }  

    public StringBuffer getResult(){

       return buffer;

    }  

}

再看看导出数据到XML文件的生成器实现,示例代码如下:

/**

 * 实现导出数据到XML文件的的生成器对象

 */

public class XmlBuilder implements Builder {

    /**

     * 用来记录构建的文件的内容,相当于产品

     */

    private StringBuffer buffer = new StringBuffer();

 

    public void buildBody(

Map<String, Collection<ExportDataModel>> mapData){

       buffer.append("  <Body>\n");

       for(String tblName : mapData.keySet()){

           //先拼接表名称

           buffer.append(

"    <Datas TableName=\""+tblName+"\">\n");

           //然后循环拼接具体数据

           for(ExportDataModel edm : mapData.get(tblName)){

              buffer.append("      <Data>\n");

              buffer.append("        <ProductId>"

+edm.getProductId()+"</ProductId>\n");

              buffer.append("        <Price>"+edm.getPrice()

+"</Price>\n");

              buffer.append("        <Amount>"+edm.getAmount()

+"</Amount>\n");

              buffer.append("      </Data>\n");

           }

           buffer.append("    </Datas>\n");

       }

       buffer.append("  </Body>\n");

    }

    public void buildFooter(ExportFooterModel efm) {

       buffer.append("  <Footer>\n");

       buffer.append("    <ExportUser>"+efm.getExportUser()

+"</ExportUser>\n");

       buffer.append("  </Footer>\n");

       buffer.append("</Report>\n");

    }

    public void buildHeader(ExportHeaderModel ehm) {

       buffer.append(

"<?xml version='1.0' encoding='gb2312'?>\n");

       buffer.append("<Report>\n");

       buffer.append("  <Header>\n");

       buffer.append("    <DepId>"+ehm.getDepId()+"</DepId>\n");

       buffer.append("    <ExportDate>"+ehm.getExportDate()

+"</ExportDate>\n");

       buffer.append("  </Header>\n");

    }

    public StringBuffer getResult(){

       return buffer;

    }

}

(4)指导者

有了具体的生成器实现后,需要有指导者来指导它进行具体的产品构建,由于构建的产品是文本内容,所以就不用单独定义产品对象了。示例代码如下:

/**

 * 指导者,指导使用生成器的接口来构建输出的文件的对象

 */

public class Director {

    /**

     * 持有当前需要使用的生成器对象

     */

    private Builder builder;

    /**

     * 构造方法,传入生成器对象

     * @param builder 生成器对象

     */

    public Director(Builder builder) {

       this.builder = builder;

    }

 

    /**

     * 指导生成器构建最终的输出的文件的对象

     * @param ehm 文件头的内容

     * @param mapData 数据的内容

     * @param efm 文件尾的内容

     */

    public void construct(ExportHeaderModel ehm,

Map<String,Collection<ExportDataModel>> mapData,

ExportFooterModel efm) {

       //1:先构建Header

       builder.buildHeader(ehm);

       //2:然后构建Body

       builder.buildBody(mapData);

       //3:然后构建Footer

       builder.buildFooter(efm);

    }

}

(5)都实现得差不多了,该来写个客户端好好测试一下了。示例代码如下:

public class Client {

    public static void main(String[] args) {

       //准备测试数据

       ExportHeaderModel ehm = new ExportHeaderModel();

       ehm.setDepId("一分公司");

       ehm.setExportDate("2010-05-18");

      

       Map<String,Collection<ExportDataModel>> mapData =

new HashMap<String,Collection<ExportDataModel>>();

       Collection<ExportDataModel> col =

new ArrayList<ExportDataModel>();

      

       ExportDataModel edm1 = new ExportDataModel();

       edm1.setProductId("产品001号");

       edm1.setPrice(100);

       edm1.setAmount(80);

      

       ExportDataModel edm2 = new ExportDataModel();

       edm2.setProductId("产品002号");

       edm2.setPrice(99);

       edm2.setAmount(55);     

       //把数据组装起来

       col.add(edm1);

       col.add(edm2);      

       mapData.put("销售记录表", col);

      

       ExportFooterModel efm = new ExportFooterModel();

       efm.setExportUser("张三");

      

       //测试输出到文本文件

       TxtBuilder txtBuilder = new TxtBuilder();

       //创建指导者对象

       Director director = new Director(txtBuilder);

       director.construct(ehm, mapData, efm);

       //把要输出的内容输出到控制台看看

       System.out.println("输出到文本文件的内容:\n"

+txtBuilder.getResult());

       //测试输出到xml文件

       XmlBuilder xmlBuilder = new XmlBuilder();

       Director director2 = new Director(xmlBuilder);

       director2.construct(ehm, mapData, efm);

       //把要输出的内容输出到控制台看看

       System.out.println("输出到XML文件的内容:\n"

+xmlBuilder.getResult());

    }

}

看了上面的示例会发现,其实生成器模式也挺简单的,好好理解一下。通过上面的讲述,应该能很清晰的看出生成器模式的实现方式和它的优势所在了,那就是对同一个构建过程,只要配置不同的生成器实现,就会生成出不同表现的对象。

ps:转载私塾在线

分享到:
评论

相关推荐

    (创建型模式)Builder模式

    2. **复杂对象的构建**:对于拥有众多属性和复杂构建过程的对象,Builder模式可以将构建过程分解为多个步骤,使得代码更易于理解和维护。 3. **分离接口和实现**:Builder模式将产品的构建和表示分离,使得用户可以...

    设计模式-Builder模式demo

    Builder模式是一种创建型设计模式,它提供了一种创建对象的抽象接口,并允许子类按照步骤构建复杂的对象。这种模式将对象的创建过程分离出来,使得同样的构造过程可以创建不同的表示,从而实现对象创建过程的解耦。 ...

    Builder模式

    2. 当产品对象的属性之间存在依赖关系时,Builder模式可以确保正确的构建顺序,避免因属性设置不当导致的对象状态错误。 3. 在产品创建过程中需要使用系统中的其他对象,且这些对象在创建过程中不易获取时,Builder...

    设计模式 创建型模式 Builder模式(建造者)

    Builder模式 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 统设计中,有时候面临着一个“复杂系统”的创建工作,该对象通常由各个部分的子对象用一定的算法构成,或者说按一定的...

    builder设计模式源码

    在Java或者其他面向对象编程语言中,Builder模式经常被用来提高代码的可读性和可维护性。 Builder模式的核心包括四个角色:Product(产品类)、ConcreteBuilder(具体建造者)、Builder(抽象建造者)和Director...

    设计模式之建造者Builder模式

    **建造者模式(Builder Pattern)**是软件设计模式中的一种,属于创建型模式。它将复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式通常用于那些需要大量构造参数的对象,通过...

    Builder模式在Java中的应用

    在设计模式中对Builder模式的定义是用于构建复杂对象的一种模式,所构建的对象往往需要多步初始化或赋值才能完成。那么,在实际的开发过程中,我们哪些地方适合用到Builder模式呢?其中使用Builder模式来替代多参数...

    BUILDER模式 C++实现

    Builder模式是一种设计模式,它属于创建型模式,主要用于复杂对象的构建。在C++中,Builder模式可以帮助我们分步骤地创建一个复杂的对象,而无需关注这些步骤如何组合在一起。这样可以使得构造过程更加灵活,同时也...

    创建型——Builder模式

    Builder模式是一种创建型设计模式,它提供了一种创建对象的灵活方式,将对象的构建过程与表示分离。这种模式在复杂对象的构造过程中特别有用,因为它允许我们通过不同的步骤来构造对象,而不会让客户端代码受到这些...

    Builder 模式

    Builder模式是一种设计模式,它属于创建型模式,主要用于构建复杂对象。这种模式允许我们通过分离对象的构造过程和表示来创建对象,使得构造过程可以更加灵活,并且能够避免在构造过程中对对象状态的直接修改。...

    (设计模式)Builder

    在给定的博客链接中,可能详细讨论了如何在实际项目中应用Builder模式,例如在软件开发工具或框架中,通过Builder模式来构建数据结构或配置对象。Builder模式能够帮助开发者将对象的创建过程分解为一系列步骤,使得...

    【Java面试题】builder模式

    【Java面试题】builder模式

    设计模式之创建模式Builder

    2. 抽象建造者(Builder):定义了构建产品对象的接口,通常包括多个构建和装配产品的部分。 3. 具体建造者(Concrete Builder):实现抽象建造者的接口,具体负责构建和组装产品对象的各个部分。 4. 导演类...

    builder设计模式

    Builder模式的核心组成部分包括: 1. **产品类(Product)**:这是要构建的复杂对象。Product类通常有多个组成部件,例如ProductPart。在给定的例子中,`product.cpp`和`productpart.cpp`可能包含了这些类的定义。 ...

    Builder模式Demo

    Builder模式是一种设计模式,它属于创建型模式,主要用于复杂对象的构建。在Builder模式中,一个Builder类会一步一步构造所创建的对象。用户可以对建造过程逐步控制,而不必关心对象内部细节,从而使得构建过程更加...

    生成器模式builder

    Builder模式属于创建型设计模式,它的核心思想是将对象的创建过程与对象本身分离,使得同样的构建过程可以创建不同的表示。 在Java或其他面向对象语言中,生成器模式通常包括四个主要角色:产品(Product)、建造者...

    软件体系结构Builder模式浅谈

    Builder模式是一种设计模式,主要目的是将复杂对象的构建与表示分离,使得构建过程可以独立于表示进行。在软件工程中,当需要创建的对象具有多个可变组成部分时,Builder模式能够帮助我们构造这些对象,同时保持构建...

    晨会分享Builder设计模式

    文件可能还包含了Builder模式与其他设计模式(如工厂模式、抽象工厂模式)的对比,以及如何在Java、C#等编程语言中使用Builder模式的示例代码。通过学习这个文件,可以深入理解Builder模式,并掌握如何在项目中有效...

    builder模式示例代码

    Builder模式是一种设计模式,主要用来创建复杂对象,它将对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。在Android开发中,Builder模式被广泛应用于创建视图或者复杂的对象配置,例如Intent的构造...

    Builder(建造模式)

    Builder模式是一种设计模式,它属于创建型模式,主要用于构建复杂对象。这种模式提供了一种方法来分离开对象的构造过程和表示方式,使得构造过程可以按照步骤进行,并且允许用户只指定他们关心的部分,而忽略其他不...

Global site tag (gtag.js) - Google Analytics