关闭

构建器

61人阅读 评论(0) 收藏 举报
分类:

今天看了 《Effective Java》第二条: 遇到多个构造器参数时要考虑用构建器。做下学习笔记。

有时候一个类的域有很多,但并不是在创建时就需要的,可能必须的只有几个,那么我们会考虑构造器重载,例如一个商户有商户名,商户编码,所属代理商,法人姓名,身份证,地址等等,其中商户名和商户编码是必须的,那么只要提供一个这2个参数的构造器并且重载一些构造器即可,代码如下。

public class Merchant {
	
	private String merchantName;
	private String merchantCode;
	private String agentCode;
	private String corporateName;
	private String identity;
	private String addr;
	
	public Merchant(String merchantName, String merchantCode) {
		this.merchantName = merchantName;
		this.merchantCode = merchantCode;
	}

	public Merchant(String merchantName, String merchantCode, String agentCode) {
		super();
		this.merchantName = merchantName;
		this.merchantCode = merchantCode;
		this.agentCode = agentCode;
	}

	public Merchant(String merchantName, String merchantCode, String agentCode, String corporateName) {
		super();
		this.merchantName = merchantName;
		this.merchantCode = merchantCode;
		this.agentCode = agentCode;
		this.corporateName = corporateName;
	}

	public Merchant(String merchantName, String merchantCode, String agentCode, String corporateName, String identity) {
		super();
		this.merchantName = merchantName;
		this.merchantCode = merchantCode;
		this.agentCode = agentCode;
		this.corporateName = corporateName;
		this.identity = identity;
	}

	public Merchant(String merchantName, String merchantCode, String agentCode, String corporateName, String identity,
			String addr) {
		super();
		this.merchantName = merchantName;
		this.merchantCode = merchantCode;
		this.agentCode = agentCode;
		this.corporateName = corporateName;
		this.identity = identity;
		this.addr = addr;
	}
	
}

很明显,这里才6个域,如果有很多呢,很不方便,于是我们可以采用javabean的方式,现在也大多使用框架开发,也都是JavaBean的方式,那么不管多少个域,只要提供set、get方法,然后再提供一个无参构造器就行了,如下:

public class Merchant {

	private String merchantName;
	private String merchantCode;
	private String agentCode;
	private String corporateName;
	private String identity;
	private String addr;

	public String getMerchantName() {
		return merchantName;
	}

	public void setMerchantName(String merchantName) {
		this.merchantName = merchantName;
	}

	public String getMerchantCode() {
		return merchantCode;
	}

	public void setMerchantCode(String merchantCode) {
		this.merchantCode = merchantCode;
	}

	public String getAgentCode() {
		return agentCode;
	}

	public void setAgentCode(String agentCode) {
		this.agentCode = agentCode;
	}

	public String getCorporateName() {
		return corporateName;
	}

	public void setCorporateName(String corporateName) {
		this.corporateName = corporateName;
	}

	public String getIdentity() {
		return identity;
	}

	public void setIdentity(String identity) {
		this.identity = identity;
	}

	public String getAddr() {
		return addr;
	}

	public void setAddr(String addr) {
		this.addr = addr;
	}

}

这是我们大多数时候使用的方式,书中指出了这种方式的缺点:因为构造过程被分到了几个调用中,在构造过程中JavaBean可能处于不一致的状态,类无法仅仅通过检验构造器参数的有效性来保证一致性。试图使用处于不一致状态的对象,将会导致失败,这种失败与包含错误的代码大相径庭,因此调试起来十分困难。另外,JavaBean模式阻止了把类做成不可变的可能,就需要程序员付出额外的努力来确保他的线程安全。

这部分我现在还不是很好的理解。

除了重载构造器和JavaBean模式外,还可以使用构建器的方式,如下:

public class Merchant {

	private String merchantName;
	private String merchantCode;
	private String agentCode;
	private String corporateName;
	private String identity;
	private String addr;

	public static class Builder {
		private String merchantName;
		private String merchantCode;
		private String agentCode;
		private String corporateName;
		private String identity;
		private String addr;
		
		public Builder(String mchName, String code) {
			this.merchantName = mchName;
			this.merchantCode = code;
		}
		
		public Builder agent(String agentCode) {
			this.agentCode = agentCode;
			return this;
		}
		
		public Builder corporate(String corporateName) {
			this.corporateName = corporateName;
			return this;
		}
		
		public Builder identity(String identity) {
			this.identity = identity;
			return this;
		}
		
		public Builder address(String addr) {
			this.addr = addr;
			return this;
		}
		
		public Merchant build() {
			return new Merchant(this);
		}
	}
	
	private Merchant(Builder builder) {
		this.addr = builder.addr;
		this.identity = builder.identity;
		this.corporateName = builder.corporateName;
		this.agentCode = builder.agentCode;
	}

}

使用构建器的话就很灵活了,采用链式调用,如:

Merchant mer = new Merchant.Builder("测试商户", "M0001").agent("A0223").address("北京西直门外大街").build();

构建器优点:

1.有多个可变参数,构造器只能有一个;

2.比JavaBean安全;

缺点:

1.创建对象必须先创建他的构建器;

2.代码比重载构造器更冗长。


现在对此的理解还不是很深入,但算是多一种思路吧,以后有新的想法再来补充。


0
0
查看评论

Java构建器(Builder)

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

Java构建器模式

构建器模式只适用于需要传入很多种情况参数的时候,比如大于4种参数的配合,才比较划算。 而且值得注意的是:最好在类的设计之初就考虑是否使用构建器,否则日后扩展起来新构建器旧构造器一起用维护起来不方便。
  • h3c4lenovo
  • h3c4lenovo
  • 2014-08-19 20:05
  • 6231

构建器模式

1.问题场景:设计某个类时,需要传入多个构造器参数(如6个参数),且这些参数中有必选参数(2个)和非必选参数(4个),那么该如何设计该类的构造器会更为合理呢? 方案一:重叠构造器模式 方案二:JavaBeans模式 方案三:构建器模式 ... ... 2.重叠构造器模式 (1)形式:先提供一个包...
  • tscyds
  • tscyds
  • 2016-04-14 23:33
  • 627

mybatis_user_guide(7) SQL语句构建器类

【0】README 1)本文全文总结于  http://www.mybatis.org/mybatis-3/zh/statement-builders.html 【1】在Java代码中来动态生成SQL代码就是一场噩梦 1)problem+solutions: 1.1)proble...
  • PacosonSWJTU
  • PacosonSWJTU
  • 2016-06-20 21:08
  • 746

mybatis-SQL语句构建器(七)

SQL语句构建器类 问题 Java程序员面对的最痛苦的事情之一就是在Java代码中嵌入SQL语句。这么来做通常是由于SQL语句需要动态来生成-否则可以将它们放到外部文件或者存储过程中。正如你已经看到的那样,MyBatis在它的XML映射特性中有一个强大的动态SQL生成方案。但有时在Java代码内...
  • u012758088
  • u012758088
  • 2017-02-10 14:27
  • 839

SQL查询Java构建器:Object Query

Object Query是一个简单的Java查询构建器,利用它能够编写类型安全和重构性查询。并且不需要绑定持久化引擎。 ? 1 2 3 4 5 6 SelectQuery query = new GenericSelectQuery(Person...
  • down177
  • down177
  • 2014-11-16 23:11
  • 248

JAVA构建器Builder模式

/** * 构建器Builder模式 * Android中的AlertDialog的构建器模式 */ public class Lunch { private String cake; private String meat; private Stri...
  • earbao
  • earbao
  • 2014-07-01 16:14
  • 4655

Google Analytics(分析)网址构建器

http://www.google.com/support/googleanalytics/bin/answer.py?hl=cn&answer=55578  有用信息 广告系列来源(utm_source)要求。 使用 utm_source 来标识搜索引擎、简报名称或其他...
  • zzw945
  • zzw945
  • 2010-03-18 15:45
  • 691

mybatis系列-SQL语句构建器类(六)

SQL语句构建器类 问题 Java程序员面对的最痛苦的事情之一就是在Java代码中嵌入SQL语句。这么来做通常是由于SQL语句需要动态来生成-否则可以将它们放到外部文件或者存储过程中。正如你已经看到的那样,MyBatis在它的XML映射特性中有一个强大的动态SQL生成方案。但有时在Java代码内...
  • xiangjai
  • xiangjai
  • 2016-12-21 10:18
  • 829

ArcGIS Pro 简明教程(4)工具和模型构建器

ArcGIS Pro 简明教程(4)工具和模型构建器 by 李远祥 工具箱中的工具        ArcGIS Pro 在1.3版本基本上已经继承了ArcMap的所有工具,而且会不断加入一些它自身才有的工具,例如适量切边工具等。可以看出,E...
  • liyuanxiang1984
  • liyuanxiang1984
  • 2016-10-10 14:24
  • 4161
    个人资料
    • 访问:538次
    • 积分:84
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类