重構第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

相關文章
相關標籤/搜索