Java不可变类–构建器模式

时间:2020-02-23 14:36:38  来源:igfitidea点击:

在上一篇文章中,我解释了Java中的Builder模式。
有时我写了一篇关于如何在Java中创建不可变类的文章。
在本文中,我们将学习使用Builder模式创建Java不可变类的简便性。
当构造函数中的参数数量更多而可能导致其顺序混乱时,使用构造器模式创建不可变类是一种好方法。

Java不可变类要点

  • 不可变类应仅具有getter方法。

  • 不可变类将具有一个带有Builder对象作为参数的私有构造函数,该私有构造函数将用于创建不可变类。

  • 如果不可更改的类属性不是不可更改的,例如HashMap,则应执行深度复制或者克隆操作,以避免修改其属性。

  • 当不可变类中的可选属性数量更多时,使用Builder模式很容易。

Java不可变类–构建器模式

这是使用Builder模式在Java中实现不变类的实现。

package com.theitroad.design.builder;

import java.util.HashMap;

public class ImmutableClass {
	
	//required fields
	private int id;
	private String name;
	
	//optional fields
	private HashMap<String, String> properties;
	private String company;
	
	public int getId() {
		return id;
	}

	public String getName() {
		return name;
	}

	public HashMap<String, String> getProperties() {
		//return cloned object to avoid changing it by the client application
		return (HashMap<String, String>) properties.clone();
	}

	public String getCompany() {
		return company;
	}

	private ImmutableClass(ImmutableClassBuilder builder) {
		this.id = builder.id;
		this.name = builder.name;
		this.properties = builder.properties;
		this.company = builder.company;
	}
	
      //Builder class
	public static class ImmutableClassBuilder{
		//required fields
		private int id;
		private String name;
		
		//optional fields
		private HashMap<String, String> properties;
		private String company;
		
		public ImmutableClassBuilder(int i, String nm){
			this.id=i;
			this.name=nm;
		}
		
		public ImmutableClassBuilder setProperties(HashMap<String,String> hm){
			this.properties = (HashMap<String, String>) hm.clone();
			return this;
		}
		
		public ImmutableClassBuilder setCompany(String comp){
			this.company = comp;
			return this;
		}
		
		public ImmutableClass build(){
			return new ImmutableClass(this);
		}
	}
}

这是测试程序,用于检查我们创建的对象是否不可变。

package com.theitroad.design.test;

import java.util.HashMap;

import com.theitroad.design.builder.ImmutableClass;

public class ImmutableBuilderTest {

	public static void main(String[] args) {
		
		//Getting immutable class only with required parameters
		ImmutableClass immutableClass = new ImmutableClass.ImmutableClassBuilder(1, "hyman").build();
		
		HashMap<String,String> hm = new HashMap<String, String>();
		hm.put("Name", "hyman");
		hm.put("City", "San Jose");
		//Getting immutable class with optional parameters
		ImmutableClass immutableClass1 = new ImmutableClass.ImmutableClassBuilder(1, "hyman")
                                                   .setCompany("Apple").setProperties(hm).build();
		
		//Testing immutability
		HashMap<String,String> hm1 = immutableClass1.getProperties();
		
		//lets modify the Object passed as argument or get from the Object
		hm1.put("test", "test");
		hm.put("test", "test");
		
		//check that immutable class properties are not changed
		System.out.println(immutableClass1.getProperties());
	}

}