重构第1天:封装集合(Encapsulate Collection)

理解:封装集合就是把集合进行封装,只提供调用者所须要的功能行借口,保证集合的安全性。安全

详解:在大多的时候,咱们没有必要把全部的操做暴露给调用者,只须要把调用者须要的相关操做暴露给他,这种状况中下咱们就要对其进行封装,只把调用者须要的部分暴露出来。spa

咱们先看一个例子:code

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace _31DaysOfReflactor
 7 {
 8     public class Order
 9     {
10         private List<OrderLine> _orderLines;
11         private double _orderTotal;
12 
13         public IList<OrderLine> OrderLines
14         {
15             get { return _orderLines; }
16         }
17 
18         public void AddOrderLine(OrderLine orderLine)
19         {
20             _orderTotal += orderLine.Total;
21             _orderLines.Add(orderLine);
22         }
23 
24         public void RemoveOrderLine(OrderLine orderLine)
25         {
26             orderLine = _orderLines.Find(o => o == orderLine);
27 
28             if (orderLine == null)
29                 return;
30 
31             _orderTotal -= orderLine.Total;
32             _orderLines.Remove(orderLine);
33         }
34     }
35 
36     public class OrderLine
37     {
38         public double Total { get; private set; }
39     }
40 }

 若是咱们对集合只容许调用端读取,遍历取值,而不容许其修改集合的值,那么咱们把IList换成了IEnumerable。IEnumerable只包括一个返回值为IEnumerator的GetEnumerator()方法,用来遍历取值,就达到咱们想要的目的。blog

重构后的代码以下:rem

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace _31DaysOfReflactor
 7 {
 8     public class Order
 9     {
10         private List<OrderLine> _orderLines;
11         private double _orderTotal;
12 
13         public IEnumerable<OrderLine> OrderLines
14         {
15             get { return _orderLines; }
16         }
17 
18         public void AddOrderLine(OrderLine orderLine)
19         {
20             _orderTotal += orderLine.Total;
21             _orderLines.Add(orderLine);
22         }
23 
24         public void RemoveOrderLine(OrderLine orderLine)
25         {
26             orderLine = _orderLines.Find(o => o == orderLine);
27 
28             if (orderLine == null)
29                 return;
30 
31             _orderTotal -= orderLine.Total;
32             _orderLines.Remove(orderLine);
33         }
34     }
35 
36     public class OrderLine
37     {
38         public double Total { get; private set; }
39     }
40 }

如上所示,咱们对IList集合进行封装,没有把该集合的add/remove方法暴露给调用端。固然在.Net framework中提供了不少封装好的集合类,不一样的类都有不一样的做用,好比ReadOnlyCollection 集合,可是他们每一个集合都有本身的使用局限性。上面的重构是一个值得注意的很是简单的例子,像这样的封装可以确保客户端不会错误的调用集合以避免引进bugs。get

相关文章
相关标签/搜索