重构随笔: 封装集合(Encapsulate Collection)

时间:2022-09-03 07:30:10

本文章节均取自《31DaysRefactoring》,非常感谢该书作者写出这么好的小书。有兴趣的同志可以看一下原著,特此声明。重构随笔: 封装集合(Encapsulate Collection)

 

 在某些特定的情况下,类的接口方法(这里指公开的方法)返回一个集合是一个很方便的做法。这样使用这个类方法的其他类可以方便的枚举和使用集合中的各个元素。但是我们时刻要谨记,集合是一个引用类型,它通过方法传递的时候,是按引用传递的,也就是说实际传出的是集合的“首地址”。为了安全和不引起不必要的麻烦,特别是当返回这个集合的类中有操作这个集合元素的一些方法,而这个类不希望别的类修改这个集合以防止出现诡异的bug时,通常的做法有以下几种:

做法(1): 新创建一个集合,然后返回新的集合给调用的方法,比如返回一个新的ReadonlyCollection之类的,这个很直接,就不给代码了。

做法(2): 返回一个只能迭代取值而不能修改原始集合的类型(通常是广义的接口类型,这样就减少了集合的可操作方法)

例如下面的代码,红色的部分是属性的返回值,在重构前,返回的是List<OrderLine>,重构以后返回的是IEnumerable<OrderLine>:

public class Order
 {
private List<OrderLine> _orderLines;

   public IEnumerable<OrderLine> OrderLines
   {
get { return _orderLines; }
}

   public void AddOrderLine(OrderLine orderLine)
{
_orderTotal += orderLine.Total;
_orderLines.Add(orderLine);
}

public void RemoveOrderLine(OrderLine orderLine)
{
orderLine = _orderLines.Find(o => o == orderLine);
     if (orderLine == null) return;

     _orderTotal -= orderLine.Total
_orderLines.Remove(orderLine);
}
 }