首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件开发 >

研磨设计形式 之 生成器模式(Builder)1 ——跟着cc学设计系列

2012-11-12 
研磨设计模式 之 生成器模式(Builder)1 ——跟着cc学设计系列8.1? 场景问题8.1.1? 继续导出数据的应用框架在

研磨设计模式 之 生成器模式(Builder)1 ——跟着cc学设计系列

8.1? 场景问题

8.1.1? 继续导出数据的应用框架

在讨论工厂方法模式的时候,提到了一个导出数据的应用框架。

对于导出数据的应用框架,通常在导出数据上,会有一些约定的方式,比如导出成:文本格式、数据库备份形式、Excel格式、Xml格式等等。

在工厂方法模式章节里面,讨论并使用工厂方法模式来解决了如何选择具体导出方式的问题,并没有涉及到每种方式具体如何实现。

换句话说,在讨论工厂方法模式的时候,并没有讨论如何实现导出成文本、Xml等具体的格式,本章就来讨论这个问题。

对于导出数据的应用框架,通常对于具体的导出内容和格式是有要求的,假如现在有如下的要求,简单描述一下:

  • 导出的文件,不管什么格式,都分成三个部分,分别是文件头、文件体和文件尾
  • 在文件头部分,需要描述如下信息:分公司或门市点编号、导出数据的日期,对于文本格式,中间用逗号分隔
  • 在文件体部分,需要描述如下信息:表名称、然后分条描述数据。对于文本格式,表名称单独占一行,数据描述一行算一条数据,字段间用逗号分隔。
  • 在文件尾部分,需要描述如下信息:输出人

    现在就要来实现上述功能。为了演示简单点,在工厂方法模式里面已经实现的功能,这里就不去重复了,这里只关心如何实现导出文件,而且只实现导出成文本格式和XML格式就可以了,其它的就不去考虑了。

    8.1.2? 不用模式的解决方案

    ?????? 不就是要实现导出数据到文本文件和XML文件吗,其实不管什么格式,需要导出的数据是一样的,只是具体导出到文件中的内容,会随着格式的不同而不同。

    (1)先来把描述文件各个部分的数据对象定义出来,先看描述输出到文件头的内容的对象,示例代码如下:

    /**

    ?* 描述输出到文件头的内容的对象

    ?*/

    public class ExportHeaderModel {

    ??? /**

    ??? ?* 分公司或门市点编号

    ??? ?*/

    ??? private String depId;

    ??? /**

    ??? ?* 导出数据的日期

    ??? ?*/

    ??? private String exportDate;

    ??? public String getDepId() {

    ?????? return depId;

    ??? }

    ??? public void setDepId(String depId) {

    ?????? this.depId = depId;

    ??? }

    ??? public String getExportDate() {

    ?????? return exportDate;

    ??? }

    ??? public void setExportDate(String exportDate) {

    ?????? this.exportDate = exportDate;

    ??? }

    }

    接下来看看描述输出数据的对象,示例代码如下:

    /**

    ?* 描述输出数据的对象

    ?*/

    public class ExportDataModel {

    ??? /**

    ??? ?* 产品编号

    ??? ?*/

    ??? private String productId;

    ??? /**

    ??? ?* 销售价格

    ??? ?*/

    ??? private double price;

    ??? /**

    ??? ?* 销售数量

    ??? ?*/

    ??? private double amount;

    ?

    ??? public String getProductId() {

    ?????? return productId;

    ??? }

    ??? public void setProductId(String productId) {

    ?????? this.productId = productId;

    ??? }

    ??? public double getPrice() {

    ?????? return price;

    ??? }

    ??? public void setPrice(double price) {

    ?????? this.price = price;

    ??? }

    ??? public double getAmount() {

    ?????? return amount;

    ??? }

    ??? public void setAmount(double amount) {

    ?????? this.amount = amount;

    ??? }

    }

    接下来看看描述输出到文件尾的内容的对象,示例代码如下:

    /**

    ?* 描述输出到文件尾的内容的对象

    ?*/

    public class ExportFooterModel {

    ??? /**

    ??? ?* 输出人

    ??? ?*/

    ??? private String exportUser;

    ??? public String getExportUser() {

    ?????? return exportUser;

    ??? }

    ??? public void setExportUser(String exportUser) {

    ?????? this.exportUser = exportUser;

    ??? }

    }

    (2)接下来具体的看看导出的实现,先看导出数据到文本文件的对象,主要就是要实现拼接输出的内容,示例代码如下:

    /**

    ?* 导出数据到文本文件的对象

    ?*/

    public class ExportToTxt {

    ??? /**

    ??? ?* 导出数据到文本文件

    ??? ?* @param ehm 文件头的内容

    ??? ?* @param mapData 数据的内容

    ??? ?* @param efm 文件尾的内容

    ??? ?*/

    ??? public void export(ExportHeaderModel ehm

    ,Map<String,Collection<ExportDataModel>> mapData

    ,ExportFooterModel efm){

    ?????? //用来记录最终输出的文件内容

    ?????? StringBuffer buffer = new StringBuffer();

    ?????? //1:先来拼接文件头的内容

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

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

    ?????? //2:接着来拼接文件体的内容

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

    ?????????? //先拼接表名称

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

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

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

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

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

    ?????????? }

    ?????? }

    ?????? //3:接着来拼接文件尾的内容

    ?????? buffer.append(efm.getExportUser());

    ?

    ?????? //为了演示简洁性,这里就不去写输出文件的代码了

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

    ?????? System.out.println("输出到文本文件的内容:\n"+buffer);

    ??? }

    }

    (3)接下来看看导出数据到XML文件的对象,比较麻烦,要按照XML的格式进行拼接,示例代码如下:

    /**

    ?* 导出数据到XML文件的对象

    ?*/

    public class ExportToXml {

    ??? /**

    ??? ?* 导出数据到XML文件

    ??? ?* @param ehm 文件头的内容

    ??? ?* @param mapData 数据的内容

    ??? ?* @param efm 文件尾的内容

    ??? ?*/

    ??? public void export(ExportHeaderModel ehm

    ,Map<String,Collection<ExportDataModel>> mapData

    ,ExportFooterModel efm){

    ?????? //用来记录最终输出的文件内容

    ?????? StringBuffer buffer = new StringBuffer();

    ?????? //1:先来拼接文件头的内容

    ?????? 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");

    ?????? //2:接着来拼接文件体的内容

    ?????? 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");

    ?????? //3:接着来拼接文件尾的内容

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

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

    +"</ExportUser>\n");

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

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

    ?

    ?????? //为了演示简洁性,这里就不去写输出文件的代码了

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

    ?????? System.out.println("输出到XML文件的内容:\n"+buffer);

    ??? }

    }

    (4)看看客户端,如何来使用这些对象,示例代码如下:

    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("张三");?????

    ?????? //测试输出到文本文件

    ?????? ExportToTxt toTxt = new ExportToTxt();

    ?????? toTxt.export(ehm, mapData, efm);

    ?????? //测试输出到xml文件

    ?????? ExportToXml toXml = new ExportToXml();

    ?????? toXml.export(ehm, mapData, efm);

    ??? }

    }

    运行结果如下:

    输出到文本文件的内容:

    一分公司,2010-05-18

    销售记录表

    产品001号,100.0,80.0

    产品002号,99.0,55.0

    张三

    输出到XML文件的内容:

    <?xml version='1.0' encoding='gb2312'?>

    <Report>

    ? <Header>

    ??? <DepId>一分公司</DepId>

    ??? <ExportDate>2010-05-18</ExportDate>

    ? </Header>

    ? <Body>

    ??? <Datas TableName="销售记录表">

    ????? <Data>

    ??????? <ProductId>产品001号</ProductId>

    ??????? <Price>100.0</Price>

    ??????? <Amount>80.0</Amount>

    ????? </Data>

    ????? <Data>

    ??????? <ProductId>产品002号</ProductId>

    ??????? <Price>99.0</Price>

    ??????? <Amount>55.0</Amount>

    ????? </Data>

    ??? </Datas>

    ? </Body>

    ? <Footer>

    ??? <ExportUser>张三</ExportUser>

    ? </Footer>

    </Report>

    8.1.3? 有何问题

    仔细观察上面的实现,会发现,不管是输出成文本文件,还是输出到XML文件,在实现的时候,步骤基本上都是一样的,都大致分成了如下四步:

    • 先拼接文件头的内容
    • 然后拼接文件体的内容
    • 再拼接文件尾的内容
    • 最后把拼接好的内容输出出去成为文件

      也就是说,对于不同的输出格式,处理步骤是一样的,但是具体每步的实现是不一样的。按照现在的实现方式,就存在如下的问题:

      (1)构建每种输出格式的文件内容的时候,都会重复这几个处理步骤,应该提炼出来,形成公共的处理过程

      (2)今后可能会有很多不同输出格式的要求,这就需要在处理过程不变的情况下,能方便的切换不同的输出格式的处理

      换句话来说,也就是构建每种格式的数据文件的处理过程,应该和具体的步骤实现分开,这样就能够复用处理过程,而且能很容易的切换不同的输出格式。

      可是该如何实现呢?

      ?


      ---------------------------------------

      私塾在线学习网原创内容 ?跟着cc学设计系列 之?研磨设计模式

      原创内容,转载请注明出处【http://sishuok.com/forum/blogPost/list/0/5084.html】

      ---------------------------------------

热点排行