02-遇到多个构造器参数时要考虑用构建器

目录

  1. 简介重叠构造器
  2. JavaBeans 模式
  3. Builder 模式
  4. Builder 模式在 Android 的应用

简介

构造器和静态工厂有一定的局限性,当我们创建实例,遇到大量的参数,有的参数需要传值,有的参数不需要选择等等灵活的条件下,我们应该怎么办?

  1. 重叠构造器:简单粗暴,提供好多好多个构造函数来满足需要。

  2. JavaBeans 模式:实际上是先调用无参的构造函数来创建对象,然后再调用属性的 setter 方法来设置每个必要的参数,以及每个可选参数。

  3. Builder 模式:此模式不直接生成想要的对象。首先客户端使用必要的参数调用构造器(或静态工厂方法),得到一个builder对象;然后客户端在 builder 对象上调用类似于 setter 的方法来设置可选参数;最后调用无参的 build 方法来生成不可变的对象,这个builder是它构建的类的静态成员类。


重叠构造器

在这举个最简单的例子,学生类如下:

public class Student {
	
	private String Name;
	private int ID;
	private int age;
	private String MClass;
	private String Phone;
	private String address;
	
	public Student(String name, int iD) {
		this(name,iD,0);
	}
	
	public Student(String name, int iD, int age) {
		this(name,iD,age,"软件工程班");
	}
	
	public Student(String name, int iD, int age, String mClass) {
		this(name,iD,age,mClass,"0");
	}
	
	public Student(String name, int iD, int age, String mClass, String phone) {
		this(name,iD,age,mClass,phone,"China");
	}
	
	public Student(String name, int iD, int age, String mClass, String phone,String address) {
		this.Name = name;
		this.ID = iD;
		this.age = age;
		this.MClass = mClass;
		this.Phone = phone;
		this.address = address;
	}
	
}

当我们想要创建实例时,我们必须要传入必要参数 Name 和 ID ,如下:

Student mStudent=new Student("pm", 12345678);

当我们需要再传入 Address 的值时,好多参数我们不得不为其传入默认值,这样看起来…就算恶心还没得家吧,如果再增加6个参数,并且需要灵活选择参数,那么构造函数就炸了…

Student mStudent2=new Student("pm", 12345678,0,"","","青岛市");

一句话:遇到很多参数时,重叠构造器可行,但是代码会很难编写,而且难以阅读。


JavaBeans模式

把学生类改成这样:

public class Student {
	
	private String Name;
	private int ID;
	private int age;
	private String MClass;
	private String Phone;
	private String address;
	
	public String getName() {
		return Name;
	}
	public void setName(String name) {
		Name = name;
	}
	
	public void setID(int iD) {
		ID = iD;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
	
	public void setMClass(String mClass) {
		MClass = mClass;
	}
	
	public void setPhone(String phone) {
		Phone = phone;
	}
	
	public void setAddress(String address) {
		this.address = address;
	}	
}

这种模式弥补了构造器模式的不足,创建实例很容易,可读性也不错。

Student mStudent=new Student();
mStudent.setName("pm");
mStudent.setID(12345678);
mStudent.setAddress("青岛市");

据书中说…
javaBeans模式自身存在着严重缺点:

  1. 在构造过程中,被分到了几个调用中,JavaBeans可能处于不一致的状态,使用处于不一致状态的对象,将会产生错误。
  2. JavaBeans模式阻止了把类做成不可变的可能,这就需要程序猿尽力确保线程安全。

一句话:这种模式很少使用。


Builder 模式

把学生类再改成这样:

public class Student {

	private final String name;
	private final int ID;
	private final int age;
	private final String mClass;
	private final String phone;
	private final String address;

	/**
	 * 学生类的静态成员类
	 * 
	 * @author GUOFENG
	 * 
	 */
	public static class Bulider {
	
		private final String name;
		private final int ID;
		private int age = 0;
		private String mClass = null;
		private String phone = null;
		private String address = null;

		public Bulider(String name, int id) {
			this.name = name;
			this.ID = id;
		}

		public Bulider age(int a) {
			age = a;
			return this;
		}

		public Bulider mClass(String c) {
			mClass = c;
			return this;
		}

		public Bulider phone(String p) {
			phone = p;
			return this;
		}

		public Bulider address(String add) {
			address = add;
			return this;
		}

		public Student bulid() {
			return new Student(this);
		}
	}

	/**
	 * 把上面设置好的bulider抠出来
	 * 
	 * @param bulider
	 */
	private Student(Bulider bulider) {
		name = bulider.name;
		ID = bulider.ID;
		age = bulider.age;
		mClass = bulider.mClass;
		phone = bulider.phone;
		address = bulider.address;
	}
}

想怎么设置就怎么设置,想怎么玩就怎么玩:

Student mStudent = new Student.Bulider("pm", 12345678).address("青岛市").bulid();

既保证像重叠构造器那样的安全性,也保证有着 javaBeans 模式的可读性。

一句话:设计类,构造器或者静态工厂中具有多个参数,Builder模式是不错的选择。


Builder 模式在 Android 的应用

在 android 编程中,使用当然也是特别广泛,比如,通过 Notification.Builder 创建通知的代码片段:

	Notification.Builder myBuilder = new Notification.Builder(context);
	myBuilder.setContentTitle(context.getString(R.string.app_name))
    .setContentText(content)
    .setTicker("您收到新的 " + context.getString(R.string.app_name) + " 消息")
	.setSmallIcon(R.mipmap.ic_launcher)
    .setAutoCancel(true)//点击后取消
    .setWhen(System.currentTimeMillis())//设置通知时间
    .setPriority(Notification.PRIORITY_HIGH)//高优先级
    .setContentIntent(pi);  //3.关联PendingIntent
    
	Notification mNotification= myBuilder.build();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值