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

封装的意义:

  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(); }
} //方法二:返回只读类型
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。

封装集合(Encapsulate Collection)的更多相关文章

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

    理解:封装集合就是把集合进行封装,只提供调用者所需要的功能行借口,保证集合的安全性. 详解:在大多的时候,我们没有必要把所有的操作暴露给调用者,只需要把调用者需要的相关操作暴露给他,这种情况中下我们就 ...

  2. 【Java重构系列】重构31式之封装集合

    2009年,Sean Chambers在其博客中发表了31 Days of Refactoring: Useful refactoring techniques you have to know系列文 ...

  3. Java集合框架Collection

    转自:http://www.cdtarena.com/javapx/201306/8891.html [plain] view plaincopyprint?01.在 Java2中,有一套设计优良的接 ...

  4. 牛客网Java刷题知识点之Java 集合框架的构成、集合框架中的迭代器Iterator、集合框架中的集合接口Collection(List和Set)、集合框架中的Map集合

    不多说,直接上干货! 集合框架中包含了大量集合接口.这些接口的实现类和操作它们的算法. 集合容器因为内部的数据结构不同,有多种具体容器. 不断的向上抽取,就形成了集合框架. Map是一次添加一对元素. ...

  5. Java | 集合(Collection)和迭代器(Iterator)

    集合(Collection) 集合就是Java中提供的一种 空器,可以用来存储多个数据. 集合和数组都是一个容器,它们有什么区别呢? 数组的长度是固定的,集合的长度是可变的. 数组中存储的是同一类型的 ...

  6. java集合 之 Collection和Iterator接口

    Collection是List,Queue和Set接口的父接口,该接口里定义的方法即可用于操作Set集合,也可以用于List和Queue集合.Collection接口里定义了如下操作元素的方法. bo ...

  7. -1-3 java集合框架基础 java集合体系结构 Collection 常用java集合框架 如何选择集合 迭代器 泛型 通配符概念 Properties 集合 迭代器

    集合又称之为容器存储对象的一种方式 •数组虽然也可以存储对象,但长度是固定的:显然需要可变长度的容器 集合和数组的区别?                 A:长度区别                  ...

  8. Java集合(Collection)综述

    1.集合简介 数学定义:一般地,我们把研究对象统称为元素.把一些元素组成的总体叫做集合. java集合定义:集合就是一个放数据的容器,准确的说是放数据对象引用的容器. java中通用集合类存放于jav ...

  9. 集合框架-Collection与List集合

    对象数组的内存图解: 集合的继承体系图解: * 数组和集合的区别? * A:长度区别 * 数组的长度固定 * 集合长度可变 * B:内容不同 * 数组存储的是同一种类型的元素 * 而集合可以存储不同类 ...

  10. backbone学习笔记:集合(Collection)

    集合(Collection)是一个Backbone对象,用来组织和管理多个模型,它不仅仅是一个javascript数组,还提供了专门的方法来对集合进行排序.过滤和遍历,集合可以方便的与REST服务器进 ...

随机推荐

  1. 说说Makefile那些事儿

    说说Makefile那些事儿 |扬说|透过现象看本质 工作至今,一直对Makefile半知半解.突然某天幡然醒悟,觉得此举极为不妥,只得洗心革面从头学来,以前许多不明觉厉之处顿时茅塞顿开,想想好记性不 ...

  2. 移动web基本知识

    1.pixel像素基础 1.px:csspixel 逻辑像素,浏览器所使用的抽象单位 2.dp,pt:设备无关像素 3.devicePixelPatio 设备像素缩放比例 2.viewport 1. ...

  3. Gradle配置APK自动签名完整流程

    转载请注明出处:http://www.cnblogs.com/LT5505/p/6256683.html 一.生成签名 1.命令行生成签名,输入命令keytool -genkey -v -keysto ...

  4. MySQL中interactive_timeout和wait_timeout的区别

    在用mysql客户端对数据库进行操作时,打开终端窗口,如果一段时间没有操作,再次操作时,常常会报如下错误: ERROR (HY000): Lost connection to MySQL server ...

  5. Spring resource bundle多语言,单引号format异常

    Spring resource bundle多语言,单引号format异常 前言 十一假期被通知出现大bug,然后发现是多语言翻译问题.法语中有很多单引号,单引号在format的时候出现无法匹配问题. ...

  6. Activity之概览屏幕(Overview Screen)

    概览屏幕 概览屏幕(也称为最新动态屏幕.最近任务列表或最近使用的应用)是一个系统级别 UI,其中列出了最近访问过的 Activity 和任务. 用户可以浏览该列表并选择要恢复的任务,也可以通过滑动清除 ...

  7. Vim使用

    模式 ESC\Ctrl+c:退出编辑模式 ZZ\wq:命令模式下保存退出 编辑 i:进入编辑模式 I:转到行首非空字符开始编辑 s:删除当前字符进入编辑模式 a:从当前字符后开始编辑 A:从当前行末非 ...

  8. OpenGL shader 中关于顶点坐标值的思考

    今天工作中需要做一个事情: 在shader内部做一些空间距离上的计算,而且需要对所有的点进行计算,符合条件的显示,不符合条件的点不显示. 思路很简单,在vertex shader内知道顶点坐标,进行计 ...

  9. BRDF 光照模型

    http://blog.csdn.net/liu_lin_xm/article/details/4846144

  10. ASP.NET Web API 路由对象介绍

    ASP.NET Web API 路由对象介绍 前言 在ASP.NET.ASP.NET MVC和ASP.NET Web API这些框架中都会发现有路由的身影,它们的原理都差不多,只不过在不同的环境下作了 ...