zoukankan      html  css  js  c++  java
  • 重构第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。

  • 相关阅读:
    【大厂面试06期】谈一谈你对Redis持久化的理解?
    【大厂面试05期】说一说你对MySQL中锁的了解?
    【大厂面试04期】讲讲一条MySQL更新语句是怎么执行的?
    【大厂面试03期】MySQL是怎么解决幻读问题的?
    【大厂面试02期】Redis过期key是怎么样清理的?
    【大厂面试01期】高并发场景下,如何保证缓存与数据库一致性?
    透过面试题掌握Redis【持续更新中】
    MySQL慢查询优化(线上案例调优)
    分享一个集成.NET Core+Swagger+Consul+Polly+Ocelot+IdentityServer4+Exceptionless+Apollo+SkyWalking的微服务开发框架
    微服务框架Demo.MicroServer运行手册
  • 原文地址:https://www.cnblogs.com/yplong/p/5276598.html
Copyright © 2011-2022 走看看