JAVA设计模式 — 生成器模式(Builder)_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > JAVA设计模式 — 生成器模式(Builder)

JAVA设计模式 — 生成器模式(Builder)

 2014/8/12 16:05:04  jy00509336  程序员俱乐部  我要评论(0)
  • 摘要:转载自:http://blog.csdn.net/top_code/article/details/8469297定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。类型:对象创建型模式类图:Builder:生成器接口,定义创建一个Product对象所需要的各个部件的操作。ConcreteBuilder:具体的生成器实现,实现各个部件的创建,并负责组装Product对象的各个部件,同时还提供一个让用户获取组装完成后的产品对象的方法。Director:指导者
  • 标签:Java 模式 设计 设计模式

转载自:http://blog.csdn.net/top_code/article/details/8469297

?

定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

类型:对象创建型模式

类图:

?

  • Builder:生成器接口,定义创建一个Product对象所需要的各个部件的操作。
  • ConcreteBuilder:具体的生成器实现,实现各个部件的创建,并负责组装Product对象的各个部件,同时还提供一个让用户获取组装完成后的产品对象的方法。
  • Director:指导者,也被称导向者,主要用来使用Builder接口,以一个统一的过程来构建所需要的Product对象。
  • Product:产品,表示被生成器构建的复杂对象,包含多个部件。

?

?

生成器模式示例代码

1、生成器接口定义的示例代码

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片 ?
    class="dp-j">
  1. /**?
  2. ?*?生成器接口,定义创建一个产品对象所需的各个部件的操作?
  3. ?*?@author?FX_SKY?
  4. ?*?
  5. ?*/??
  6. public?interface?Builder?{??
  7. ??
  8. ????/**?
  9. ?????*?示意方法,构建某个部件?
  10. ?????*/??
  11. ????public?void?buildPart();??
  12. }??

?

?

2、具体生成器实现的示例代码

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片 ?
  1. /**?
  2. ?*?具体的生成器实现对象?
  3. ?*?@author?FX_SKY?
  4. ?*?
  5. ?*/??
  6. public?class?ConcreteBuilder?implements?Builder?{??
  7. ??????
  8. ????private?Product?resultProduct;??
  9. ??????
  10. ????/**?
  11. ?????*?获取生成器最终构建的产品对象?
  12. ?????*?@return?
  13. ?????*/??
  14. ????public?Product?getResultProduct()?{??
  15. ????????return?resultProduct;??
  16. ????}??
  17. ??
  18. ????@Override??
  19. ????public?void?buildPart()?{??
  20. ????????//构建某个部件的功能处理??
  21. ????}??
  22. ??
  23. }??

?

?

3、相应的产品对象接口的示例代码

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片 ?
  1. /**?
  2. ?*?被构建的产品对象的接口?
  3. ?*?@author?FX_SKY?
  4. ?*?
  5. ?*/??
  6. public?interface?Product?{??
  7. ????//定义产品的操作??
  8. }??

?

?

4、最后是指导者的实现示意,示例代码如下:

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片 ?
  1. /**?
  2. ?*?指导者,指导使用生成器的接口来构建产品对象?
  3. ?*?@author?FX_SKY?
  4. ?*?
  5. ?*/??
  6. public?class?Director?{??
  7. ??
  8. ????/**?
  9. ?????*?持有当前需要使用的生成器对象?
  10. ?????*/??
  11. ????private?Builder?builder;??
  12. ??
  13. ????/**?
  14. ?????*?构造方法,传人生成器对象?
  15. ?????*?@param?builder?
  16. ?????*/??
  17. ????public?Director(Builder?builder)?{??
  18. ????????this.builder?=?builder;??
  19. ????}??
  20. ??????
  21. ????/**?
  22. ?????*?示意方法,指导生成器构建最终的产品对象?
  23. ?????*/??
  24. ????public?void?construct(){??
  25. ????????//通过使用生成器接口来构建最终的产品对象??
  26. ????????builder.buildPart();??
  27. ????}??
  28. }??

?

?

应用场景-- 导出数据的应用框架

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

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

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

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

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

?

  • 导出的文件,不管是什么格式,都分成3个部分,分别是文件头、文件体、文件尾。
  • 在文件头部分,需要描述如下信息:分公司或者门市编号、导出数据的日期。
  • 在文件体部分,需要描述如下信息:表名称,然后分条描述数据。
  • 在文件尾部分,需要描述如下信息:输出人。

?

?

1、下面将描述文件各个部分的数据对象定义出来

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

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片 ?
  1. /**?
  2. ?*?描述输出到文件头的内容的对象?
  3. ?*?@author?FX_SKY?
  4. ?*?
  5. ?*/??
  6. public?class?ExportHeaderModel?{??
  7. ??
  8. ????/**?
  9. ?????*?分公司或者门市编号?
  10. ?????*/??
  11. ????private?String?depId;??
  12. ????/**?
  13. ?????*?导出数据的日期?
  14. ?????*/??
  15. ????private?String?exportDate;??
  16. ??????
  17. ????public?String?getDepId()?{??
  18. ????????return?depId;??
  19. ????}??
  20. ????public?void?setDepId(String?depId)?{??
  21. ????????this.depId?=?depId;??
  22. ????}??
  23. ????public?String?getExportDate()?{??
  24. ????????return?exportDate;??
  25. ????}??
  26. ????public?void?setExportDate(String?exportDate)?{??
  27. ????????this.exportDate?=?exportDate;??
  28. ????}??
  29. ??????
  30. }??

?

?

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

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片 ?
  1. /**?
  2. ?*?描述输出数据的对象?
  3. ?*?@author?FX_SKY?
  4. ?*?
  5. ?*/??
  6. public?class?ExportDataModel?{??
  7. ??
  8. ????/**?
  9. ?????*?产品编号?
  10. ?????*/??
  11. ????private?String?productId;??
  12. ????/**?
  13. ?????*?销售价格?
  14. ?????*/??
  15. ????private?double?price;??
  16. ????/**?
  17. ?????*?销售数量?
  18. ?????*/??
  19. ????private?double?amount;??
  20. ??????
  21. ????public?String?getProductId()?{??
  22. ????????return?productId;??
  23. ????}??
  24. ????public?void?setProductId(String?productId)?{??
  25. ????????this.productId?=?productId;??
  26. ????}??
  27. ????public?double?getPrice()?{??
  28. ????????return?price;??
  29. ????}??
  30. ????public?void?setPrice(double?price)?{??
  31. ????????this.price?=?price;??
  32. ????}??
  33. ????public?double?getAmount()?{??
  34. ????????return?amount;??
  35. ????}??
  36. ????public?void?setAmount(double?amount)?{??
  37. ????????this.amount?=?amount;??
  38. ????}??
  39. ??????
  40. }??

?

?

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

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片 ?
  1. /**?
  2. ?*?描述输出到文件尾的内容的对象?
  3. ?*?@author?FX_SKY?
  4. ?*?
  5. ?*/??
  6. public?class?ExportFooterModel?{??
  7. ??
  8. ????/**?
  9. ?????*?输出人?
  10. ?????*/??
  11. ????private?String?exportUser;??
  12. ??
  13. ????public?String?getExportUser()?{??
  14. ????????return?exportUser;??
  15. ????}??
  16. ??
  17. ????public?void?setExportUser(String?exportUser)?{??
  18. ????????this.exportUser?=?exportUser;??
  19. ????}??
  20. ??????
  21. }??


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

?

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片 ?
  1. /**?
  2. ?*?生成器接口,定义创建一个输出文件对象所需的各个部件的操作?
  3. ?*?@author?FX_SKY?
  4. ?*?
  5. ?*/??
  6. public?interface?Builder?{??
  7. ??
  8. ????/**?
  9. ?????*?构建输出文件的Header部分?
  10. ?????*?@param?ehm?
  11. ?????*/??
  12. ????public?void?buildHeader(ExportHeaderModel?ehm);??
  13. ??????
  14. ????/**?
  15. ?????*?构建输出文件的Body部分?
  16. ?????*?@param?mapData?
  17. ?????*/??
  18. ????public?void?buildBody(Map<String,List<ExportDataModel>>?mapData);??
  19. ??????
  20. ????/**?
  21. ?????*?构建输出文件的Footer部分?
  22. ?????*?@param?efm?
  23. ?????*/??
  24. ????public?void?buildFooter(ExportFooterModel?efm);??
  25. }??


3、具体的生成器实现。

?

导出到文本文件的的生成器实现。示例代码如下:

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片 ?
  1. /**?
  2. ?*?实现导出文件到文本文件的生成器对象?
  3. ?*?@author?FX_SKY?
  4. ?*?
  5. ?*/??
  6. public?class?TxtBuilder?implements?Builder?{??
  7. ??
  8. ????/**?
  9. ?????*?用来记录构建的文件的内容,相当于产品?
  10. ?????*/??
  11. ????private?StringBuffer?buffer?=?new?StringBuffer();??
  12. ??????
  13. ????@Override??
  14. ????public?void?buildHeader(ExportHeaderModel?ehm)?{??
  15. ????????buffer.append(ehm.getDepId()+","+ehm.getExportDate()+"\n");??
  16. ????}??
  17. ??
  18. ????@Override??
  19. ????public?void?buildBody(Map<String,?List<ExportDataModel>>?mapData)?{??
  20. ????????for(String?tablName?:?mapData.keySet()){??
  21. ??????????????
  22. ????????????//先拼接表名??
  23. ????????????buffer.append(tablName+"\n");??
  24. ????????????//然后循环拼接具体数据??
  25. ????????????for(ExportDataModel?edm?:?mapData.get(tablName)){??
  26. ????????????????buffer.append(edm.getProductId()+","+edm.getPrice()+","+edm.getAmount()+"\n");??
  27. ????????????}??
  28. ????????}??
  29. ????}??
  30. ??
  31. ????@Override??
  32. ????public?void?buildFooter(ExportFooterModel?efm)?{??
  33. ????????buffer.append(efm.getExportUser());??
  34. ????}??
  35. ??????
  36. ????public?StringBuffer?getResult(){??
  37. ????????return?buffer;??
  38. ????}??
  39. ??
  40. }??

?

?

导出到Xml文件的的生成器实现。示例代码如下:

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片 ?
  1. /**?
  2. ?*?实现导出文件到Xml文件的生成器对象?
  3. ?*?@author?FX_SKY?
  4. ?*?
  5. ?*/??
  6. public?class?XmlBuilder?implements?Builder?{??
  7. ??
  8. ????/**?
  9. ?????*?用来记录构建的文件的内容,相当于产品?
  10. ?????*/??
  11. ????private?StringBuffer?buffer?=?new?StringBuffer();??
  12. ??????
  13. ????@Override??
  14. ????public?void?buildHeader(ExportHeaderModel?ehm)?{??
  15. ????????buffer.append("<?xml?version='1.0'?encoding='UTF-8'?>\n");??
  16. ????????buffer.append("<Report>\n");??
  17. ????????buffer.append("\t<Header>\n");??
  18. ????????buffer.append("\t\t<DepId>"+ehm.getDepId()+"</DepId>\n");??
  19. ????????buffer.append("\t\t<ExportDate>"+ehm.getExportDate()+"</ExportDate>\n");??
  20. ??????????
  21. ????????buffer.append("\t</Header>\n");??
  22. ????}??
  23. ??
  24. ????@Override??
  25. ????public?void?buildBody(Map<String,?List<ExportDataModel>>?mapData)?{??
  26. ????????buffer.append("\t<Body>\n");??
  27. ????????for(String?tablName?:?mapData.keySet()){??
  28. ????????????//先拼接表名??
  29. ????????????buffer.append("\t\t<Datas?TableName=\""+tablName+"\">\n");??
  30. ????????????//然后循环拼接具体数据??
  31. ????????????for(ExportDataModel?edm?:?mapData.get(tablName)){??
  32. ??????????????????
  33. ????????????????buffer.append("\t\t\t<Data>\n");??
  34. ??????????????????
  35. ????????????????buffer.append("\t\t\t\t<ProductId>"+edm.getProductId()+"</ProductId>\n");??
  36. ????????????????buffer.append("\t\t\t\t<Price>"+edm.getPrice()+"</Price>\n");??
  37. ????????????????buffer.append("\t\t\t\t<Amount>"+edm.getAmount()+"</Amount>\n");??
  38. ??????????????????
  39. ????????????????buffer.append("\t\t\t</Data>\n");??
  40. ????????????}??
  41. ??????????????
  42. ????????????buffer.append("\t\t</Datas>\n");??
  43. ????????}??
  44. ????????buffer.append("\t</Body>\n");??
  45. ????}??
  46. ??
  47. ????@Override??
  48. ????public?void?buildFooter(ExportFooterModel?efm)?{??
  49. ????????buffer.append("\t<Footer>\n");??
  50. ????????buffer.append("\t\t<ExportUser>"+efm.getExportUser()+"</ExportUser>\n");??
  51. ????????buffer.append("\t</Footer>\n");??
  52. ????????buffer.append("</Report>\n");??
  53. ????}??
  54. ??????
  55. ????public?StringBuffer?getResult(){??
  56. ????????return?buffer;??
  57. ????}??
  58. ??
  59. }??

?

?

4、指导者。有了具体的生成器实现后,需要由指导者来指导它进行具体的产品构建。示例代码如下:

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片 ?
  1. /**?
  2. ?*?指导者,指导使用生成器的接口来构建输出的文件对象?
  3. ?*??
  4. ?*?@author?FX_SKY?
  5. ?*??
  6. ?*/??
  7. public?class?Director?{??
  8. ??
  9. ????/**?
  10. ?????*?持有当前需要的使用的生成器对象?
  11. ?????*/??
  12. ????private?Builder?builder;??
  13. ??
  14. ????/**?
  15. ?????*?构造方法,传入生成器对象?
  16. ?????*??
  17. ?????*?@param?builder?
  18. ?????*/??
  19. ????public?Director(Builder?builder)?{??
  20. ????????this.builder?=?builder;??
  21. ????}??
  22. ??
  23. ????public?void?construct(ExportHeaderModel?ehm,??
  24. ????????????Map<String,?List<ExportDataModel>>?mapData,?ExportFooterModel?efm)?{??
  25. ??
  26. ????????//1.先构建Header??
  27. ????????builder.buildHeader(ehm);??
  28. ??????????
  29. ????????//2.然后构建Body??
  30. ????????builder.buildBody(mapData);??
  31. ??????????
  32. ????????//3.再构建Footer??
  33. ????????builder.buildFooter(efm);??
  34. ????}??
  35. }??

?

?

5、客户端测试代码如下:

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片 ?
  1. public?class?Client?{??
  2. ??
  3. ????/**?
  4. ?????*?@param?args?
  5. ?????*/??
  6. ????public?static?void?main(String[]?args)?{??
  7. ??????????
  8. ????????//准备测试数据??
  9. ????????ExportHeaderModel?ehm?=?new?ExportHeaderModel();??
  10. ????????ehm.setDepId("一分公司");??
  11. ????????ehm.setExportDate("2010-05-18");??
  12. ??????????
  13. ????????Map<String,?List<ExportDataModel>>?mapData?=?new?HashMap<String,?List<ExportDataModel>>();??
  14. ????????List<ExportDataModel>?col?=?new?ArrayList<ExportDataModel>();??
  15. ??????????
  16. ????????ExportDataModel?edm1?=?new?ExportDataModel();??
  17. ????????edm1.setProductId("产品001号");??
  18. ????????edm1.setPrice(100);??
  19. ????????edm1.setAmount(80);??
  20. ??????????
  21. ????????ExportDataModel?edm2?=?new?ExportDataModel();??
  22. ????????edm2.setProductId("产品002号");??
  23. ????????edm2.setPrice(120);??
  24. ????????edm2.setAmount(280);??
  25. ??????????
  26. ????????ExportDataModel?edm3?=?new?ExportDataModel();??
  27. ????????edm3.setProductId("产品003号");??
  28. ????????edm3.setPrice(320);??
  29. ????????edm3.setAmount(380);??
  30. ??????????
  31. ????????col.add(edm1);??
  32. ????????col.add(edm2);??
  33. ????????col.add(edm3);??
  34. ??????????
  35. ????????mapData.put("销售记录表",?col);??
  36. ??????????
  37. ????????ExportFooterModel?efm?=?new?ExportFooterModel();??
  38. ????????efm.setExportUser("张三");??
  39. ??????????
  40. ????????//测试输出到文本文件??
  41. ????????TxtBuilder?txtBuilder?=?new?TxtBuilder();??
  42. ????????//创建指导者对象??
  43. ????????Director?director?=?new?Director(txtBuilder);??
  44. ????????director.construct(ehm,?mapData,?efm);??
  45. ??????????
  46. ????????//把要输出的内容输出到控制台看看??
  47. ????????System.out.println("输出到文本文件的内容:"+txtBuilder.getResult().toString());??
  48. ??????????
  49. ????????XmlBuilder?xmlBuilder?=?new?XmlBuilder();??
  50. ????????Director?director2?=?new?Director(xmlBuilder);??
  51. ????????director2.construct(ehm,?mapData,?efm);??
  52. ??????????
  53. ????????//把要输出的内容输出到控制台看看??
  54. ????????System.out.println("输出到Xml文件的内容:"+xmlBuilder.getResult().toString());??
  55. ????}??
  56. ??
  57. }??

?

?

生成器模式的功能

生成器模式的主要功能是构建复杂的产品,而且是细化的,分步骤的构建产品,也就是生成器模式重在一步一步解决构造复杂对象的问题。如果仅仅这么认知生成器模式的功能是不够的。

更为重要的是,这个构建的过程是统一的、固定不变的,变化的部分放到生成器部分了,只要配置不同的生成器,那么同样的构建过程,就能构建出不同的产品来。

?

使用生成器模式构建复杂的对象

考虑这样的一个实际应用,Android图片异步加载框架,需要要创建图片加载配置的对象,里面很多属性的值都有约束,要求创建出来的对象是满足这些约束规则的。约束规则比如,线程池的数量不能小于2个、内存图片缓存的大小不能为负值等等。

?

要想简洁直观、安全性好,有具有很好的扩展性地创建这个对象的话,一个较好的选择就是使用Builder模式,把复杂的创建过程通过Builder来实现。

采用Builder模式来构建复杂的对象,通常会对Builder模式进行一定的简化,因为目标明确,就是创建某个复杂对象,因此做适当简化会使程序更简洁。大致简化如下:

?

  • 由于是用Builder模式来创建某个对象,因此就没有必要再定义一个Builder接口,直接提供一个具体的构建器类就可以了。
  • 对于创建一个负责的对象,可能会有很多种不同的选择和步骤,干脆去掉“指导者”,把指导者的功能和Client的功能合并起来,也就是说,Client就相当于指导者,它来指导构建器类去构建需要的复杂对象。

?

?

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片 ?
  1. public?final?class?ImageLoaderConfiguration?{??
  2. ??
  3. ????final?Executor?taskExecutor;??
  4. ??
  5. ????final?int?memoryCacheSize;??
  6. ??????
  7. ????final?int?threadPoolSize;??
  8. ????final?int?threadPriority;??
  9. ??
  10. ????final?boolean?writeLogs;??
  11. ??
  12. ????private?ImageLoaderConfiguration(final?Builder?builder)?{??
  13. ????????taskExecutor?=?builder.taskExecutor;??
  14. ????????threadPoolSize?=?builder.threadPoolSize;??
  15. ????????threadPriority?=?builder.threadPriority;??
  16. ????????memoryCacheSize?=?builder.memoryCacheSize;??
  17. ????????writeLogs?=?builder.writeLogs;??
  18. ????}??
  19. ??
  20. ????/**?
  21. ?????*?Builder?for?{@link?ImageLoaderConfiguration}?
  22. ?????*?
  23. ?????*?@author?Sergey?Tarasevich?(nostra13[at]gmail[dot]com)?
  24. ?????*/??
  25. ????public?static?class?Builder?{??
  26. ??
  27. ????????public?static?final?int?DEFAULT_THREAD_POOL_SIZE?=?3;??
  28. ??????????
  29. ????????public?static?final?int?DEFAULT_THREAD_PRIORITY?=?Thread.NORM_PRIORITY?-?1;??
  30. ??
  31. ????????private?int?memoryCacheSize?=?0;??
  32. ??????????
  33. ????????private?Executor?taskExecutor?=?null;??
  34. ??
  35. ????????private?int?threadPoolSize?=?DEFAULT_THREAD_POOL_SIZE;??
  36. ????????private?int?threadPriority?=?DEFAULT_THREAD_PRIORITY;??
  37. ??
  38. ????????private?boolean?writeLogs?=?false;??
  39. ??
  40. ????????public?Builder()?{??
  41. ????????}??
  42. ??
  43. ????????public?Builder?taskExecutor(Executor?executor)?{??
  44. ????????????if?(threadPoolSize?!=?DEFAULT_THREAD_POOL_SIZE?||?threadPriority?!=?DEFAULT_THREAD_PRIORITY)?{??
  45. ??????????????
  46. ????????????}??
  47. ??
  48. ????????????this.taskExecutor?=?executor;??
  49. ????????????return?this;??
  50. ????????}??
  51. ??
  52. ????????public?Builder?threadPoolSize(int?threadPoolSize)?{??
  53. ??
  54. ????????????this.threadPoolSize?=?threadPoolSize;??
  55. ????????????return?this;??
  56. ????????}??
  57. ??
  58. ????????public?Builder?threadPriority(int?threadPriority)?{??
  59. ??
  60. ????????????if?(threadPriority?<?Thread.MIN_PRIORITY)?{??
  61. ????????????????this.threadPriority?=?Thread.MIN_PRIORITY;??
  62. ????????????}?else?{??
  63. ????????????????if?(threadPriority?>?Thread.MAX_PRIORITY)?{??
  64. ????????????????????this.threadPriority?=?Thread.MAX_PRIORITY;??
  65. ????????????????}?else?{??
  66. ????????????????????this.threadPriority?=?threadPriority;??
  67. ????????????????}??
  68. ????????????}??
  69. ????????????return?this;??
  70. ????????}??
  71. ??
  72. ????????public?Builder?memoryCacheSize(int?memoryCacheSize)?{??
  73. ????????????if?(memoryCacheSize?<=?0)?throw?new?IllegalArgumentException("memoryCacheSize?must?be?a?positive?number");??
  74. ??
  75. ????????????this.memoryCacheSize?=?memoryCacheSize;??
  76. ????????????return?this;??
  77. ????????}??
  78. ??
  79. ????????public?Builder?writeDebugLogs()?{??
  80. ????????????this.writeLogs?=?true;??
  81. ????????????return?this;??
  82. ????????}??
  83. ??
  84. ????????/**?Builds?configured?{@link?ImageLoaderConfiguration}?object?*/??
  85. ????????public?ImageLoaderConfiguration?build()?{??
  86. ????????????initEmptyFieldsWithDefaultValues();??
  87. ????????????return?new?ImageLoaderConfiguration(this);??
  88. ????????}??
  89. ??
  90. ????????private?void?initEmptyFieldsWithDefaultValues()?{??
  91. ????????????if?(taskExecutor?==?null)?{??
  92. ??????????????????
  93. ????????????}??
  94. ????????}??
  95. ????}??
  96. }??

客户端调用示例代码如下:

?

?

[java]?view plaincopy在CODE上查看代码片派生到我的代码片 ?
  1. public?class?Client?{??
  2. ??
  3. ????/**?
  4. ?????*?@param?args?
  5. ?????*/??
  6. ????public?static?void?main(String[]?args)?{??
  7. ??????????
  8. ????????ImageLoaderConfiguration??config?=?new?ImageLoaderConfiguration.Builder()??
  9. ????????.taskExecutor(Executors.newCachedThreadPool())??
  10. ????????.threadPoolSize(3)??
  11. ????????.threadPriority(Thread.MIN_PRIORITY?+?3)??
  12. ????????.memoryCacheSize(1024*16)??
  13. ????????.build();??
  14. ????}??
  15. ??
  16. }??

?

?

生成器模式的优点

松散耦合

生成器模式可以用同一个构建算法构建出表现上完全不同的产品,实现产品构建和产品表现上的分离。生成器模式正是把产品构建的过程独立出来,使它和具体产品的表现分松散耦合,从而使得构建算法可以复用,而具体产品表现也可以很灵活地、方便地扩展和切换。

可以很容易的改变产品的内部表示

在生成器模式中,由于Builder对象只是提供接口给Director使用,那么具体部件创建和装配方式是被Builder接口隐藏了的,Director并不知道这些具体的实现细节。这样一来,要想改变产品的内部表示,只需要切换Builder接口的具体实现即可,不用管Director,因此变得很容易。

更好的复用性

生成器模式很好的实现构建算法和具体产品实现的分离。这样一来,使得构建产品的算法可以复用。同样的道理,具体产品的实现也可以复用,同一个产品的实现,可以配合不同的构建算法使用。

?

生成器模式的本质:分离整体构建算法和部件构造。

虽然在生成器模式的整体构建算法中,会一步一步引导Builder来构建对象,但这并不是说生成器主要就是用来实现分步骤构建对象的。生成器模式的重心还是在于分离整体构建算法和部件构造,而分步骤构建对象不过是整体构建算法的一个简单表现,或者说是一个附带产物。

?

何时选用生成器模式

建议在以下情况中选用生成器模式。

?

  • 如果创建对象的算法,应该独立于该对象的组成部分以及它们的装配方式时。
  • 如果同一个构建过程有着不同的表示时。
上一篇: 画板总结 下一篇: CSharp陷阱1
发表评论
用户名: 匿名