讀《重構》,學習Collections.unmodifiableList()用法
在《重構——改善既有程式碼的設計》一書中,有一種重構手法叫Encapsulate Collection
(封裝叢集),為了演示該重構手法,我寫了四個類,通過對比重構前後的程式碼,加深對
這一重構手法的理解。
類Student有一ArrayList屬性,如果沒有閱讀《重構——改善既有程式碼的設計》一書,
很多人可能會像我一樣,如下設計類Student。但是,如果通過Student.getCourses()
獲得對ArrayList屬性引用後,就可以任意為Student物件新增“課程”,而Student物件
對此一無所知,這不符合物件導向程式設計的習慣。
package com.readonlylist;
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;
}
}
package com.readonlylist;
import java.util.ArrayList;
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類如下所示:
package com.readonlylist;
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);
}
}
package com.readonlylist;
import java.util.List;
import java.util.ArrayList;
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物件新增一個新課程。就好像,你必須讓顧客自己向購物車裡放食物,
而不能在顧客毫不知情下,偷偷向其購物車裡放食物。
真是萬物皆通情理啊:)
相關文章
- 【學習筆記】Kruskal 重構樹筆記
- kruskal重構樹學習筆記筆記
- 《重構》讀書筆記筆記
- 【讀程式碼重構有感】
- 重構讀書筆記筆記
- std::function用法學習Function
- 《CSS重構》閱讀總結CSS
- Java入門學習-學習static的用法Java
- 從重構的角度學習bridge設計模式設計模式
- 智慧指標用法學習指標
- Ajax學習(重點)
- 從重構的角度學習bridge設計模式 (轉)設計模式
- 學習AngularJs:Directive指令用法AngularJS
- Axios用法–學習筆記iOS筆記
- C++ any_of用法學習C++
- (合併 重疊陣列)練習容器的用法陣列
- Angular4學習(初始檔案目錄結構解讀)Angular
- java學習(BufferedReader & InputStreamReader 用法)Java
- mybatis 學習--mybatis基本用法入門MyBatis
- maven學習(上)- 基本入門用法Maven
- Collections.unmodifiableList方法的使用與場景
- 重審promise的用法Promise
- 【SQL 學習】去掉重複行SQL
- 重學資料結構(二、棧)資料結構
- 重學資料結構之棧資料結構
- 重學資料結構(七、圖)資料結構
- (十一)TestNG學習之路—BeanShell高階用法Bean
- 【Numpy學習】np.count_nonzero()用法解析
- python學習筆記-list的用法Python筆記
- swift 字串學習 (index用法和擷取)Swift字串Index
- 學習 instr 和decode的用法
- 精讀《原始碼學習》原始碼
- 讀書學習 寫作
- 重構(Refactoring)技巧讀書筆記 之三筆記
- 《資料結構與演算法之美》如何抓住重點,系統高效地學習資料結構與演算法 (讀後感)資料結構演算法
- 《學習JavaScript資料結構與演算法》閱讀總結JavaScript資料結構演算法
- Face++ 論文解讀:一種新的行人重識別度量學習方法
- 結構體學習結構體