Builder模式在Java中的应用

news/2024/7/7 9:39:03

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

我们常常会面临编写一个这样的实现类(假设类名叫DoDoContact),这个类拥有多个构造函数,

DoDoContact(String name);

DoDoContact(String name, int age);

DoDoContact(String name, int age, String address);

DoDoContact(String name, int age, String address, int cardID);

这样一系列的构造函数主要目的就是为了提供更多的客户调用选择,以处理不同的构造请求。这种方法很常见,也很有效力,但是它的缺点也很多。类的作者不得不书写多种参数组合的构造函数,而且其中还需要设置默认参数值,这是一个需要细心而又枯燥的工作。其次,这样的构造函数灵活性也不高,而且在调用时你不得不提供一些没有意义的参数值,例如,DoDoContact("Ace", -1, "SH"),显然年龄为负数没有意义,但是你又不的不这样做,得以符合Java的规范。如果这样的代码发布后,后面的维护者就会很头痛,因为他根本不知道这个-1是什么含义。对于这样的情况,就非常适合使用Builder模式。Builder模式的要点就是通过一个代理来完成对象的构建过程。这个代理职责就是完成构建的各个步骤,同时它也是易扩展的。下面是改写自Effective Java里面的一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public  class  DoDoContact {
     private  final  int     age;
     private  final  int     safeID;
     private  final  String name;
     private  final  String address;
  
     public  int  getAge() {
         return  age;
     }
  
     public  int  getSafeID() {
         return  safeID;
     }
  
     public  String getName() {
         return  name;
     }
  
     public  String getAddress() {
         return  address;
     }
  
     public  static  class  Builder {
         private  int     age     =  0 ;
         private  int     safeID  =  0 ;
         private  String name    =  null ;
         private  String address =  null ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 构建的步骤
         public  Builder(String name) {
             this .name = name;
         }
  
         public  Builder age( int  val) {
             age = val;
             return  this ;
         }
  
         public  Builder safeID( int  val) {
             safeID = val;
             return  this ;
         }
  
         public  Builder address(String val) {
             address = val;
             return  this ;
         }
  
         public  DoDoContact build() {  // 构建,返回一个新对象
             return  new  DoDoContact( this );
         }
     }
  
     private  DoDoContact(Builder b) {
         age = b.age;
         safeID = b.safeID;
         name = b.name;
         address = b.address;
  
     }
}

最终,客户程序可以很灵活的去构建这个对象。

1
2
3
4
DoDoContact ddc =  new  DoDoContact.Builder( "Ace" ).age( 10 )
                 .address( "beijing" ).build();
System.out.println( "name="  + ddc.getName() +  "age ="  + ddc.getAge()
                 "address"  + ddc.getAddress());


转自:http://www.cnblogs.com/moonz-wu/archive/2011/01/11/1932473.html




      本文转自布拉君君 51CTO博客,原文链接:http://blog.51cto.com/5148737/1961136,如需转载请自行联系原作者





http://www.niftyadmin.cn/n/1895476.html

相关文章

H264/AVC 参考图像管理

参考图像顺序 264中,已编码图像存储在编码器和解码器的参考缓冲区(DPB,解码图像缓冲区),并由相应的参考图像列表list0,以供帧间宏块的运动补偿预测使用。对B片预测而言,list0和list1分别包含当…

H264/AVC 数据分割片和传输

数据分割片 组成片的编码数据存放在3个独立的DP(数据分割,A、B、C)中,各自包含一个编码片的子集。分割A包含片头和片中每个宏块头数据。分割B包含帧内和SI片宏块的编码残差数据。分割C包含帧间宏块的编码残差数据。每个分割可放在…

第一周 机器学习(ML)策略(1):1.5 训练 / 开发 / 测试集划分

目录 第一章、简介 第二章、训练 / 开发 / 测试集划分 2.1、训练集 / 开发集 / 测试集 的概念 2.2、如何划分开发集和测试集 2.3、开发集和测试集划分的典型例子 2.4、开发集和测试集划分的重要意义 2.5、小结 第一章、简介 本文基于吴恩达人工智能课程做学习笔记、并融…

H264/AVC 句法

在编码器输出的码流中,数据的基本单位是句法元素,每个句法元素由若干比特构成,它表示某个特定的物理意义,例如:宏块类型、量化参数等。句法表示句法元素的组织结构。 句法元素的分层结构 码流是由一个个句法元素依次衔…

H264/AVC 解码器原理

264包括VCL(视频编码层)和NAL(网络提取层),VCL包括核心压缩引擎和块、宏块和片的语法级别定义,它的设计目标是尽可能地独立于网络进行高效编码;NAL则负责将VCL产生的比特字符串适配到各种各样地…

H264/AVC NAL单元和解码

在264中,NAL是以NALU(NAL unit)为单元来支持编码数据在基于包交换技术网络中的传输的;它定义了符合传输层或存储介质需求的数据格式,同时提供头信息,从而提供了视频编码与外部世界的接口。网络层和传输层的…

第一周 机器学习(ML)策略(1):1.6 开发集与测试集的大小

目录 第一章、简介 第二章、开发集与测试集的大小 2.1、 数据集较小时 训练集/开发集/测试集 的划分规则。 2.2、数据集较大时 训练集/开发集/测试集 的划分规则。 2.3、 用置信度评估测试集的性能。 2.4、数据集较大情况下可考虑省略 测试集 2.5、小结 第一章、简介 本…

服务器端跟踪和收集

SQL Server性能分析器只是少量系统存储过程中相当轻量的封装,这些系统存储过程显示了SQL跟踪的真正功能。 下列系统存储过程用来定义和管理跟踪: Sp_trace_create 用来定义一个跟踪,并和接下来将要讲的其他选项一样指定一个输出文件位置。这个…