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


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

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

    我们先看一个例子:

     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()方法,用来遍历取值,就达到我们想要的目的。

    重构后的代码如下:

     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。

  • 相关阅读:
    2017年5月24日 HTML 基础知识(二)
    2017年5月22日 HTML基础知识(一)
    尼采语录
    Unicode字符串和整数和浮点数
    转义字符
    python第一节
    C# ASP .NET WEB方向和WPF方向,我该如何去选择
    ORA-06550:line 1,column 7;PLS-00201:indentifer '存储过程' must be declared;...PL/SQL Statement ignored 问题
    C# WPF打印报表
    Sql Server 自定义数据类型
  • 原文地址:https://www.cnblogs.com/yplong/p/5276598.html
Copyright © 2020-2023  润新知