• 重构指南


    封装就是将相关的方法或者属性抽象成为一个对象。

    封装的意义:

    1. 对外隐藏内部实现,接口不变,内部实现自由修改。
    2. 只返回需要的数据和方法。
    3. 提供一种方式防止数据被修改。
    4. 更好的代码复用。
    当一个类的属性类型为集合,或者方法返回类型为集合时,如果符合以下条件,我们就可以考虑将集合进行封装:
    1. 返回的数据仅用于展示
    2. 当集合的Add,Remove方法包含其它业务逻辑
    向类的调用者隐藏类中的完整集合有如下几个好处:
    1. 保证返回的集合数据不会被修改。
    2. 在Add, Remove方法中可以添加验证,日志或其他业务逻辑。
    代码示例:
    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; }
        }
    } 
     
    上面的代码在Add或者Remove orderLine时存在业务逻辑,如果调用时直接修改OrderLines的元素,就会产生bug,所以需要重构如下:
     
    using System.Collections.Generic;
    
    namespace LosTechies.DaysOfRefactoring.EncapsulateCollection.After
    {
        public class Order
        {
            private List<OrderLine> _orderLines;
            private double _orderTotal;
    
    //方法一:返回IEnumerable类型
            public IEnumerable<OrderLine> OrderLines
            {
                get { return _orderLines.Skip(0); }
            }
    
    //方法二:返回只读类型
             public ReadOnlyCollection<OrderLine> OrderLines
            {
                get { return _orderLines.AsReadOnly(); }
            }
            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; }
        }
    }
     
    注意:虽然直接返回IEnumerable,这样只能遍历取出它的值,但是还是可以通过转换为List后操作集合中的元素,所以我们采用_orderLines.Skip(0)迭代返回,这样就能阻止调用者转换为list。
  • 相关阅读:
    数据库---多表查询练习
    数据库---权限管理
    数据库---表---多表查询
    数据库---数据---单表查询
    软件测试面试题(3)
    windows资源监控
    测试十大原则
    性能测试关心的结果
    软件测试面试题(2)
    软件测试面试题(1)
  • 原文地址:https://www.cnblogs.com/hmloo/p/EncapsulateCollection.html
Copyright © 2020-2023  润新知