Collections.unmodifiableList()

在《重构——改善既有代码的设计》一书中,有一种重构手法叫Encapsulate Collection (封装集群),为了演示该重构手法,我写了四个类,通过对比重构前后的代码,加深对 这一重构手法的理解。

类Student有一ArrayList属性,如果没有阅读《重构——改善既有代码的设计》一书, 很多人可能会像我一样,如下设计类Student。但是,如果通过Student.getCourses() 获得对ArrayList属性引用后,就可以任意为Student对象添加“课程”,而Student对象 对此一无所知,这不符合面向对象编程的习惯。

import java.util.ArrayList;
public class Student {
	private String name;
	private ArrayList<String> courses;
	public Student(String name, ArrayList<String> courses) {
		this.name = name;
		this.courses = courses;
	}
	public ArrayList<String> getCourses() {
		return courses;
	}
	public void setCourses(ArrayList<String> courses) {
		this.courses = courses;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Test {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();
		list.add("001");
		list.add("002");
		Student s = new Student("Tom", list);
		ArrayList<String> anotherList = s.getCourses();
		anotherList.add("999");
		System.out.println("Tom's course.length = " + s.getCourses().size());
	}
}

重构后的Student类如下所示:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Student1 {
	private String name;
	private ArrayList<String> courses;
	public Student1(String name, ArrayList<String> courses) {
		this.name = name;
		this.courses = courses;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void addCourse(String course) {
		courses.add(course);
	}
	public String removeCourse(String course) {
		boolean removed = courses.remove(courses);
		if (removed) {
			return course;
		} else {
			return null;
		}
	}
	public List<String> getCourses() {
		return Collections.unmodifiableList(courses);
	}
}

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Test1 {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();
		list.add("001");
		list.add("002");
		Student1 s = new Student1("Tom", list);
		List<String> anotherList = s.getCourses();
		/**
		 * throws java.lang.UnsupportedOperationException * should replace
		 * with s.addCourse(String course)
		 */
		anotherList.add("999");
		// never reached
		System.out.println("Tom's course.length = " + s.getCourses().size());
	}

}

重构后,Student1类,仅对外提供的getCourses()方法,而没有setCourses()方法,而且 通过getCourses()方法获得的courses是“只读的”,如果你试图向其添加一个新课程,则 抛出java.lang.UnsupportedOperationException。你必须通过Student1.addCourse()来 向特定的Student1对象添加一个新课程。就好像,你必须让顾客自己向购物车里放食物, 而不能在顾客毫不知情下,偷偷向其购物车里放食物。

真是万物皆通情理啊:)

from:http://hi.baidu.com/onejava/blog/item/10388f2b77d340fae6cd4091.html

你可能感兴趣的:(Collections.unmodifiableList())