封装集合(Encapsulate Collection)
2024-10-09 14:20:11
封装就是将相关的方法或者属性抽象成为一个对象。
封装的意义:
- 对外隐藏内部实现,接口不变,内部实现自由修改。
- 只返回需要的数据和方法。
- 提供一种方式防止数据被修改。
- 更好的代码复用。
当一个类的属性类型为集合,或者方法返回类型为集合时,如果符合以下条件,我们就可以考虑将集合进行封装:
- 返回的数据仅用于展示
- 当集合的Add,Remove方法包含其它业务逻辑
向类的调用者隐藏类中的完整集合有如下几个好处:
- 保证返回的集合数据不会被修改。
- 在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。
最新文章
- pygame系列_原创百度随心听音乐播放器_完整版
- MD5签名方法
- cf div2 239 D
- angularJS $resource与后台restapi的对应关系
- hdu 3715
- SPI,UART,I2C都有什么区别,及其各自的特点
- 【转】stdin, stdout, stderr 以及重定向
- ping时不知道ping那个Ip的解决办法
- Java集合(5)一 HashMap与HashSet
- Collection集合框架详解
- JSoup抓取本地页面
- 30 个java编程技巧
- Mysql在master上查看有哪些slave
- python处理excel之读:xlrd模块
- javascript基础拾遗(二)
- <;邱永汉股票入门>;读书笔记
- width:100%和width:auto区别
- c++ 指针访问数组
- 阿里云maven仓库镜像mirror,速度超快
- CentOS按电源键关机