文章出處

今天閱讀源碼的時候,無意中看到了Collections.unmodifiableList的用法,因為以前沒有這樣做過,所以查詢了他的API,是這樣寫的

public static <T> List<T> unmodifiableList(List<? extends T> list)

參數:list--這是一個不可修改視圖是要返回的列表中。

返回值:在方法調用返回指定列表的不可修改視圖。

1、用法探討:

 1 public class CollectionsListDemo {
 2   public static void main(String[] args) {
 3 
 4       List<String> list = new ArrayList<String>();
 5       list.add("aa");
 6      list.add("bb"); 
 7      
 8       System.out.println("初始化前: "+ list);
 9      
10       //實現 unmodifiable
11       List<Character> immutablelist = Collections.unmodifiableList(list);
12      
13       //修改 list
14       immutablelist.add("zz");     
15   }}
16 
17 結果:
18 
19 初始化前:: [aa, bb]
20 
21 Exception in thread "main" java.lang.UnsupportedOperationException

2、繼續追蹤,到底什么場景遇到呢?重構是怎么寫的的?

在《重構——改善既有代碼的設計》一書中,有一種重構手法叫Encapsulate Collection  ,(封裝集合),

定義是:讓函數返回這個集合的副本,并在這個類中提供添加/移除集合的副本

為了演示該重構手法

這本書介紹的是:我們經常用集合,Collection,可能是Array,ArrayList,set,vector保存一組實例,這樣的類通常也會提供針對該集合的取值與設值函數

但是集合的處理方式和其他種類略有不同,取值函數不應該返回集合本身,因為這會讓用戶得以修改集合的內容而集合擁有者去一無所知,這樣會對用戶 暴露過多的對象的內部結構信息。如果一個取值函數確實要返回多個值,他應該避免用戶直接操作對象內保存的集合,并隱藏對象內與用戶無關的的數據結構

此外,不應該為這個集合提供一個設置函數,但是應該提供對象內集合本身添加/刪除的函數,這樣,集合擁有者(對象)就可以控制集合元素的添加與刪除

如果做到了上邊的一點,集合就很好的封裝起來,這樣就降低了集合擁有者和用戶之間的耦合度

常用到的做法:

(1)加入為集合添加/移除元素的函數

(2)將保存的集合的字段初始化一個空的集合

3、下面對上邊的內容的例子介紹:

原來我這樣寫的:

 1 import java.util.List;
 2 
 3 public class Student
 4 {
 5         private String userName ;
 6        
 7         private List<String> courses ;
 8        
 9 
10         public Student (String userName , List<String> courses)
11        {
12                this.userName = userName;
13                this.courses = courses;
14        }
15 
16         public String getUserName()
17        {
18                return userName ;
19        }
20 
21         public void setUserName(String userName)
22        {
23                this.userName = userName;
24        }
25 
26         public List<String> getCourses()
27        {
28                return courses ;
29        }
30 
31         public void setCourses(List<String> courses)
32        {
33                this.courses = courses;
34        }
35        
36        
37 
38 }

重構后,按照上面介紹的原則,這樣重構:

 1 import java.util.ArrayList;
 2 import java.util.Collections;
 3 import java.util.List;
 4 
 5 public class Student
 6 {
 7         private String userName ;
 8 
 9         private List<String> courses ;
10 
11         public Student (String userName , List<String> courses)
12        {
13                this.userName = userName;
14                this.courses = courses;
15        }
16 
17         public String getUserName()
18        {
19                return userName ;
20        }
21 
22         public void setUserName(String userName)
23        {
24                this.userName = userName;
25        }
26 
27         public void addCourse(String course)
28        {
29                courses.add(course);
30        }
31 
32         public boolean removeCourse(String course)
33        {
34                return courses .remove(courses );
35 
36        }
37 
38         public List<String> getCourses()
39        {
40                return Collections.unmodifiableList( courses);
41        }
42 
43         public static void main(String[] args)
44        {
45               List<String> list = new ArrayList<String>();
46               list.add( "數學");
47               list.add( "語文");
48               Student s = new Student("lily" , list);
49 
50               List<String> anotherList = s.getCourses();
51 
52                /**
53                * throws java.lang.UnsupportedOperationException should replace with
54                * s.addCourse(String course)
55                */
56               anotherList.add( "英語");
57 
58                // 不會走到這一步,因為上邊拋出了異常
59               System. out.println("lily's course.length = " + s.getCourses().size());
60        }
61 
62 }

4、總結

使用這種方法重構的意義:就好比我們網上購物一樣,你可以往購物車添加自己想買的東西,但是商戶不能在不通知顧客(我們)的情況下,就任意的添加商品,并修改商品的價格等,入口只能是一個,也就是在顧客手中。比喻可能不是很恰當,反正意思大概就是這樣。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()