zoukankan      html  css  js  c++  java
  • 重构指南

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

    封装的意义:

    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。
  • 相关阅读:
    数字图像-概述
    Python-python打包编译成pyd或者.so,保护代码。
    计算机组成原理-概述
    9大开源云管理平台(CMP)
    计算机组成原理-CPU-CPU知识科普:秒懂主频、核心、线程、缓存、架构详解
    svn git协同管理
    DEVTMPFS
    关于flash擦除的方法
    SQLServer强制保存
    360极速浏览器无法正确getHours
  • 原文地址:https://www.cnblogs.com/hmloo/p/EncapsulateCollection.html
Copyright © 2011-2022 走看看