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

封装的意义:

  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. Unity3d学习 预设体(prefab)的一些理解

    之前一直在想如果要在Unity3d上创建很多个具有相同结构的对象,是如何做的,后来查了相关资料发现预设体可以解决这个问题! 预设体的概念: 组件的集合体 , 预制物体可以实例化成游戏对象. 创建预设体 ...

  2. 虾扯蛋:Android View动画 Animation不完全解析

    本文结合一些周知的概念和源码片段,对View动画的工作原理进行挖掘和分析.以下不是对源码一丝不苟的分析过程,只是以搞清楚Animation的执行过程.如何被周期性调用为目标粗略分析下相关方法的执行细节 ...

  3. MVC Core 网站开发(Ninesky) 2、栏目

    栏目是网站的常用功能,按照惯例栏目分常规栏目,单页栏目,链接栏目三种类型,这次主要做添加栏目控制器和栏目模型两个内容,控制器这里会用到特性路由,模型放入业务逻辑层中(网站计划分数据访问.业务逻辑和We ...

  4. MVC通过路由实现URL重写

    public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Ro ...

  5. [原] KVM 虚拟化原理探究 —— 目录

    KVM 虚拟化原理探究 -- 目录 标签(空格分隔): KVM KVM 虚拟化原理探究(1)- overview KVM 虚拟化原理探究(2)- QEMU启动过程 KVM 虚拟化原理探究(3)- CP ...

  6. 设计模式C#合集--工厂方法模式

    简单工厂,代码: public interface ISpeak { public void Say(); } public class Hello : ISpeak { public void Sa ...

  7. ABP项目中使用Swagger生成动态WebAPI

    本文是根据角落的白板报的<使用ABP实现SwaggerUI,生成动态webapi>一文的学习总结,感谢原文作者角落的白板报. 1 安装Swashbuckle.core 1.1 选择WebA ...

  8. 【JQ基础】DOM操作

    内部插入:append() //向每个匹配的元素内部追加内容,可包含 HTML 标签 $(selector).append(function(index,html)) /*•index - 可选.接收 ...

  9. Android Socket连接PC出错问题及解决

    最近测试问题:Android 通过Socket链接电脑,ip和端口都是正确的,也在同一网段,可android端就是报异常如下: 解决办法:测试电脑的防火墙可能开着,在控制面板把防火墙打开即可.

  10. 敏捷转型历程 - Sprint3 一团糟的演示会

    我: Tech Leader 团队:团队成员分布在两个城市,我所在的城市包括我有4个成员,另外一个城市包括SM有7个成员.另外由于我们的BA离职了,我暂代IT 的PO 职位.PM和我在一个城市,但他不 ...