qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          跟屌絲大哥學習設計模式--生成器模式(Builder)

          Builder 模式的重心在于分離構建算法和具體的構造實現,從而使構建算法可以重用。

          Builder 模式的構成分為兩部分:一部分是Builder接口,定義了如何構建各個部件,并裝配到產品中去;另一部分是Director,定義如何來構建產品,Director 負責整體的構建算法,而且通常是分步來執行的。

          注:這里的構建算法是指:通過什么樣的方式來組裝產品;構建產品指的是:構建一個復雜對象。

          Builder 模式就是將構建產品部件組裝產品的過程分開,即實現了產品部件組裝產品過程的解耦,可以使得組裝產品過程得到復用



          public class ExportHeaderModel {

                   private String depId;
                   private String exportDate;
                   省略getter 和 setter
           } 

          public class ExportDataModel {

                 private String productId;
                 private double price;
                 private double amount;
                 省略getter 和 setter
          }

          public class ExportFooterModel {

                private String exportUser;

                省略getter 和 setter

           }
          /**
           * 生成器接口,定義一個輸出文件對象所需的各個部件的操作
           *
           */
          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();
           
                    @Override
                    public void buildHeader(ExportHeaderModel ehm) {
                              buffer.append(ehm.getDepId() + "," + ehm.getExportDate() + "\n");
                     }

                    @Override
                    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");
                                      }
                             }
                   }

             @Override
                   public void buildFooter(ExportFooterModel efm) {
                              buffer.append(efm.getExportUser());
                   }

                   public StringBuffer getResult(){
                             return buffer;
                   }
          }

          public class XmlBuilder implements Builder {

                    private StringBuffer buffer = new StringBuffer();
           

            @Override
                    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");
                   }
               @Override
                   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");
                  }

                @Override
                   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 StringBuffer getResult(){
                            return buffer;
                   }
          }

          /**
           * 指導者,指導使用生成器的接口來構建輸出的文件對象
           *

          /**
           * 指導者,指導使用生成器的接口來構建輸出的文件對象
           *
           */
          public class Director {

                    /**
                     * 持有當前需要使用的生成器對象
                     */
                   private Builder 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){
                               //構建Header
                               builder.buildHeader(ehm);
                               //構建Body
                               builder.buildBody(mapData);
                              //構建Footer
                               builder.buildFooter(efm);
                  }
          }

          public class Client {

                    public static void main(String[] args) {
                            ExportHeaderModel ehm = new ExportHeaderModel();
                            ehm.setDepId("一分公司");
                            ehm.setExportDate("2011-06-12");
            
                            Map<String, Collection<ExportDataModel>> mapData = new HashMap<String, Collection<ExportDataModel>>();
                            Collection<ExportDataModel> coll = new ArrayList<ExportDataModel>();
            
                            ExportDataModel edml = new ExportDataModel();
                            edml.setAmount(80);
                            edml.setProductId("產品001號");
                            edml.setPrice(100);
                            coll.add(edml);
            
                           ExportDataModel edm2 = new ExportDataModel();
                           edm2.setAmount(60);
                           edm2.setProductId("產品002號");
                           edm2.setPrice(120);
                           coll.add(edm2);
            
                          mapData.put("銷售記錄表", coll);
            
                          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());
            
                          XmlBuilder xmlBuilder = new XmlBuilder();
                         Director director2 = new Director(xmlBuilder);
                         director2.construct(ehm, mapData, efm);
                         System.out.println("輸出到Xml文件的內容:\n" + xmlBuilder.getResult());
                  }

          }

          ● 使用生成器模式創建復雜對象:

          ① 由于使用Builder 模式來創建某個對象,因此就沒有必要再定義一個Builder接口,直接提供一個具體的構建器類就可以了。

          ② 對于創建一個復雜的對象,可能會有很多種不同的選擇和步驟,干脆去掉“Director”,把Director的功能和Client 的功能合并起來,也就是說這個時候,Client 相當于指導者,它來指導構建器類去構建需要的復雜對象。

          public class ConcreteBuilder {

                  private String contractId;
                  private String personName;
                  private String companyName;
                  private long beginDate;
                  private long endDate;
                  private String otherData;
           
                 /**
                   * 構造方法 傳入必填數據
                   * @param contractId 保險合同號
                   * @param beginDate 保險開始生效的日期
                   * @param endDate 保險失效的日期
                   */
                 public ConcreteBuilder(String contractId, long beginDate, long endDate){
                          this.contractId = contractId;
                          this.beginDate = beginDate;
                          this.endDate = endDate;
                  }
                  /**
                    * 選填數據,被保險人
                    * @param personName 被保險人名
                    * @return 構建對象
                    */
                  public ConcreteBuilder setPersonName(String personName){
                            this.personName = personName;
                            return this;
                  }
                  /**
                   * 選填數據,被保險公司
                   * @param companyName 被保險公司名
                   * @return 構建對象
                   */
                 public ConcreteBuilder setCompanyName(String companyName){
                           this.companyName = companyName;
                           return this;
                  }
                  /**
                   * 選填數據,其它數據
                   * @param otherData 其它數據
                   * @return 構建對象
                   */
                  public ConcreteBuilder setOtherData(String otherData){
                          this.otherData = otherData;
                          return this;
                  }
           
                  public InsuranceContract build(){
                         if(contractId == null || contractId.trim().length() == 0){
                                  throw new IllegalArgumentException("合同編號不能空!");
                          }
            
                          boolean signPerson = (personName != null && personName.trim().length() > 0);
                          boolean signCompany = (companyName != null && companyName.trim().length() > 0);
            
                          if(!(signPerson ^ signCompany)){
                                      throw new IllegalArgumentException("一份保險不能沒有簽訂對象,且不能同時與人和公司簽訂!");
                          }
            
                         if(beginDate <= 0){
                                   throw new IllegalArgumentException("合同必須有保險開始生效的日期!");
                          }
            
                         if(endDate <= 0){
                                  throw new IllegalArgumentException("合同必須有保險失效的日期!");
                         }
            
                         if(endDate <= beginDate){
                                  throw new IllegalArgumentException("保險失效日期必須大于生效日期!");
                         }
            
                          return new InsuranceContract(this);
                   }
           
                    public String getContractId() {
                              return contractId;
                    }
                    public String getPersonName() {
                              return personName;
                    }
                    public String getCompanyName() {
                              return companyName;
                    }
                    public long getBeginDate() {
                               return beginDate;
                    }
                    public long getEndDate() {
                              return endDate;
                    }
                    public String getOtherData() {
                              return otherData;
                    }
          }

          /**
           * 保險合同對象
           * @author joe
           *
           */
          public class InsuranceContract {

                  /**
                   * 保險合同編號
                   */
                 private String constractId;
                 /**
                  * 被保險的人
                  */
                 private String personName;
                 /**
                  * 被保險的公司
                  */
                private String companyName;
                /**
                 * 保險開始生效的日期
                */
                private long beginDate;
                /**
                 * 保險失效的日期
                 */
                private long endDate;
                /**
                 * 其它數據
                 */
                private String otherData;
                /**
                 * 構造方法,訪問級別是同包能訪問
                 * @param builder
                 */
                InsuranceContract(ConcreteBuilder builder){
                       this.constractId = builder.getContractId();
                       this.personName = builder.getPersonName();
                       this.companyName = builder.getCompanyName();
                       this.beginDate = builder.getBeginDate();
                       this.endDate = builder.getEndDate();
                       this.otherData = builder.getOtherData();
                 }
           
                public void someOperation(){
                        System.out.println("Now in Insurance Contract someOperation == " + this.constractId);
                 }

          }

          public class Client {

                    public static void main(String[] args) {
                              ConcreteBuilder builder = new ConcreteBuilder("001", 82345L, 67890L);
                              InsuranceContract contract = builder.setPersonName("張三").setOtherData("test").build();
                              contract.someOperation();
                    }
          }

          posted on 2012-12-17 19:33 順其自然EVO 閱讀(193) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2012年12月>
          2526272829301
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 深州市| 隆子县| 聊城市| 兴城市| 湖北省| 荆州市| 抚顺县| 砚山县| 屯留县| 夏津县| 永州市| 炉霍县| 湄潭县| 崇信县| 图们市| 汉源县| 玉门市| 长武县| 桂林市| 桐乡市| 新平| 醴陵市| 大丰市| 哈密市| 五台县| 开阳县| 崇左市| 容城县| 常宁市| 酒泉市| 濉溪县| 邵阳市| 中宁县| 山阴县| 万安县| 宁陵县| 黔东| 东丽区| 龙游县| 泰州市| 九台市|