设计模式-小王搞设计

小王正在设计一个导出数据的应用框架。客户要求:导出数据可能存储成不同的文件格式,例如:文本格式、数据库备份形式、Excel格式、Xml格式等等,并且,不管什么格式,导出数据文件都分成三个部分,分别是文件头、文件体和文件尾,在文件头部分,需要描述如下信息:分公司或门市点编号、导出数据的日期,对于文本格式,中间用逗号分隔,在文件体部分,需要描述如下信息:表名称、然后分条描述数据,对于文本格式,表名称单独占一行,数据描述一行算一条数据,字段间用逗号分隔,在文件尾部分,需要描述如下信息:输出人。请你选择恰当的设计模式帮助小王进行设计。

/**
 * 描述输出到文件头的内容的对象
 */
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;
    }
}

/**
 * 生成器接口,定义创建一个输出文件对象所需的各个部件的操作
 */
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);
}

/**
 * 实现导出数据到文本文件的的生成器对象
 */
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文件的的生成器对象
 */
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;
    }
}

/**
 * 指导者,指导使用生成器的接口来构建输出的文件的对象
 */
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);
    }
}

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());
    }
}
2. 单例模式的本质是控制实例数目。
/** 
* 简单演示如何扩展单例模式,控制实例数目为3个  
*/  
public class OneExtend {  
    /** 
    * 定义一个缺省的key值的前缀 
    */  
    private final static String DEFAULT_PREKEY = "Cache";  
    /** 
    * 缓存实例的容器 
    */  
    private static Map<String,OneExtend> map = new HashMap<String,OneExtend>();  
    /** 
    * 用来记录当前正在使用第几个实例,到了控制的最大数目,就返回从1开始 
    */  
    private static int num = 1;  
    /** 
    * 定义控制实例的最大数目 
    */  
    private final static int NUM_MAX = 3;   
    private OneExtend(){}  
    public static OneExtend getInstance(){  
        String key = DEFAULT_PREKEY+num;  
        //缓存的体现,通过控制缓存的数据多少来控制实例数目  
        OneExtend oneExtend = map.get(key);  
        if(oneExtend==null){  
            oneExtend = new OneExtend();  
            map.put(key, oneExtend);  
        }  
        //把当前实例的序号加1  
        num++;  
        if(num > NUM_MAX){  
            //如果实例的序号已经达到最大数目了,那就重复从1开始获取  
            num = 1;  
        }  
        return oneExtend;         
    }  
      
    public static void main(String[] args) {  
        //测试是否能满足功能要求  
        OneExtend t1 = getInstance ();  
        OneExtend t2 = getInstance ();  
        OneExtend t3 = getInstance ();  
        OneExtend t4 = getInstance ();  
        OneExtend t5 = getInstance ();  
        OneExtend t6 = getInstance ();  
          
        System.out.println("t1=="+t1);  
        System.out.println("t2=="+t2);  
        System.out.println("t3=="+t3);  
        System.out.println("t4=="+t4);  
        System.out.println("t5=="+t5);  
        System.out.println("t6=="+t6);  
    }  
}  


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值