• 由Collections.unmodifiableList引发的重构


    今天阅读源码的时候,无意中看到了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、总结

    使用这种方法重构的意义:就好比我们网上购物一样,你可以往购物车添加自己想买的东西,但是商户不能在不通知顾客(我们)的情况下,就任意的添加商品,并修改商品的价格等,入口只能是一个,也就是在顾客手中。比喻可能不是很恰当,反正意思大概就是这样。

  • 相关阅读:
    java中public、private、protected区别
    Java构造函数
    吸血鬼数字算法
    JsonConvert.DeserializeObject<T>对象属性为空
    vs2015项目引用其他项目无法引用
    iis express 无法访问此网站
    c#Dictionary保存不同类型
    HttpContext.GetOwinContext().Authentication 报错 解决办法
    CSS基础1
    CSS基础3
  • 原文地址:https://www.cnblogs.com/langtianya/p/5058016.html
Copyright © 2020-2023  润新知