由Collections.unmodifiableList引发的重构

本文探讨了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、总结

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

转载于:https://www.cnblogs.com/langtianya/p/5058016.html

package com.example.kucun2.entity.data; import android.os.Handler; import android.os.Looper; import android.util.Log; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; public class SynchronizedList<T extends SynchronizableEntity> { private static final String TAG = "AsyncEntityList"; private final List<T> internalList = new CopyOnWriteArrayList<>(); private final List<ListChangeListener<T>> listeners = new ArrayList<>(); private final EntityChangeListener<T> entityChangeListener = new EntityChangeListener<>(); private Class<T> type; // 列表变更监听器接口 public interface ListChangeListener<T> { void onItemAdded(T item, int position); void onItemRemoved(T item, int position); void onSyncStarted(T item); void onSyncSuccess(T item); void onSyncFailure(T item, String error); void onListChanged(); } public Class<T> getType() { return type; } public SynchronizedList(Class<T> type) { this.type=type; } // 操作回调接口 public interface OperationCallback<T> { void onSuccess(T item); void onFailure(T item, String error); } // 注册监听器 public void addListChangeListener(ListChangeListener<T> listener) { listeners.add(listener); } // 移除监听器 public void removeListChangeListener(ListChangeListener<T> listener) { listeners.remove(listener); } // 通知所有监听器 private void notifyListeners(Runnable action) { new Handler(Looper.getMainLooper()).post(() -> { for (ListChangeListener<T> listener : listeners) { action.run(); } }); } // 异步添加元素 public void addAsync(T item, OperationCallback<T> callback) { if (item == null || internalList.contains(item)) return; // 1. 预添加状态(UI可立即显示) int position = internalList.size(); internalList.add(item); registerListener(item); notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onItemAdded(item, position); listener.onSyncStarted(item); } }); // 2. 后台执行同步 new Thread(() -> { item.sync("add", new SynchronizableEntity.SyncCallback() { @Override public void onSyncSuccess(SynchronizableEntity entity) { notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onSyncSuccess((T) entity); listener.onListChanged(); } }); if (callback != null) callback.onSuccess((T) entity); } @Override public void onSyncFailure(String error) { internalList.remove(item); unregisterListener(item); notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onSyncFailure((T) item, error); listener.onItemRemoved((T) item, position); } }); if (callback != null) callback.onFailure((T) item, error); } }); }).start(); } // 异步移除元素 public void removeAsync(T item, OperationCallback<T> callback) { if (!internalList.contains(item)) return; int position = internalList.indexOf(item); internalList.remove(item); unregisterListener(item); notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onItemRemoved(item, position); listener.onSyncStarted(item); } }); new Thread(() -> { item.sync("remove", new SynchronizableEntity.SyncCallback() { @Override public void onSyncSuccess(SynchronizableEntity entity) { notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onSyncSuccess((T) entity); } }); if (callback != null) callback.onSuccess((T) entity); } @Override public void onSyncFailure(String error) { internalList.add(position, item); // 回滚 registerListener(item); notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onSyncFailure((T) item, error); listener.onItemAdded(item, position); } }); if (callback != null) callback.onFailure((T) item, error); } }); }).start(); } // 获取不可修改的列表视图(用于RecyclerView) public List<T> getViewList() { return Collections.unmodifiableList(internalList); } // 实体变更监听器 private static class EntityChangeListener<T extends SynchronizableEntity> implements PropertyChangeListener { @Override public void propertyChange(PropertyChangeEvent evt) { ((T) evt.getSource()).sync(null); } } private void registerListener(T element) { if (element != null) { element.addPropertyChangeListener(entityChangeListener); } } private void unregisterListener(T element) { if (element != null) { element.removePropertyChangeListener(entityChangeListener); } } } removePropertyChangeListener?
最新发布
06-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值