封装集合

概念:本文所讲的封装集合就是把集合进行封装,只提供调用端需要的接口。 

正文:在很多时候,我们都不希望把一些不必要的操作暴露给调用端,只需要给它所需要的操作或数据就行,那么做法就是封装。这个重构在微软的代码库也经常遇到。比如最经典的属性对字段的封装就是一个很好的例子,那么下面我们将看到对集合的封装,如下代码所示,调用端只需要一个集合的信息,而我们则提供了一个IList的集合,大家都知道IList具有对集合的所有操作,所以这会带来很多隐患,最好的做法就是对它进行重构。

using System.Collections.Generic;

namespace LosTechies.DaysOfRefactoring.EncapsulateCollection.Before
{
public class Order
{
private List<OrderLine> _orderLines;
private double _orderTotal;

public IList<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);
}
}

public class OrderLine
{
public double Total { get; private set; }
}
}

那么重构之后,我们把IList换成了IEnumerable,大家都知道只包括一个返回值为IEnumerator的GetEnumerator()方法,所以这样只能遍历取出它的值,而不能对这个集合做出改变,这正是我们所需要的结果,具体代码如下:

using System.Collections.Generic;

namespace LosTechies.DaysOfRefactoring.EncapsulateCollection.After
{
public class Order
{
private List<OrderLine> _orderLines;
private double _orderTotal;

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);
}
}

public class OrderLine
{
public double Total { get; private set; }
}
}

总结:这个例子很容易让我们想到以前系统间耦合常喜欢用数据库。每个系统都会操作数据库,并且有些系统还会对数据库的表结构或字段进行修改,那么这很容易就会造成维护的地狱,很明智的一个做法就是使用SOA来隔开这些耦合,让一些只需要数据展示的系统得到自己需要的数据即可。

posted @ 2017-06-29 15:56  marblemm  阅读(327)  评论(0编辑  收藏  举报