相关数据是否封装/封装之后是否隐藏
2009-08-01 16:37
786 查看
当一个类包含(组合)了许多数据成员,是否需要把其中某一些相关性很大的数据提取出来,重构成一个或几个小对象,然后让原来的大类直接组合这些小对象呢?
当满足以下两种情况之一时,这种重构是有必要的:
(1)
存在专门针对这些数据的操作;
(2)
还有其它的类或package也包含这些数据。
第一种情况有必要,因为我们不仅提取了数据,也提取了方法。结果就是提取了一个同时拥有状态和行为的对象,而不仅仅是一个数据结构体。这将使原来那个大类的代码显得更加清晰,因为抽象被更好地层次化了。
第二种情况有必要,则仅仅是从代码复用的角度考虑的,抽取出来,大家都可以用,免得每次填加一个相关的新类时就需要从别人那里拷贝一大堆数据成员,也避免了当又有新的数据需要加入到这些成员中时,我们要修改一大堆类。
如果这两个条件都不满足,那么这种重构仅仅能使代码的结构和抽象稍微干净一些,并没有其它重要意义。还是省出时间来干点别的事吧。或者等代码进化到出现以上两种需求时,再重构也不迟。
然后,当我们完成这种重构之后,这些新的小类是否有必要公开给其它的类,以及其它的package呢?这就要看这个新的小类仅仅是这个类(或者这个package)的实现细节,还是一种更通用的抽象实体。
如果是后者,无疑应该公开出来。但如果是前者,那就有必要隐藏它,不让其它类知道。比如在C++语言中,把它定义在某个cpp文件中(而不是头文件中),或者在C#或J***A这样的语言中,把它定义成非公共的类。
但是,如果类的对外接口(“公共方法”,“公共成员函数”)中出现了这种新的类型,该怎么办呢?是不是就没有办法,只能公开了?比如,类有某些get和set方法是专门跟这种小对象打交道的。对于仅仅是实现细节的情况,答案仍然是:隐藏它!宁可让这些接口中出现重构之前的零散数据,也不要出现这种新的类型。因为这样可以减少类或者package之间的耦合。让外界尽量少地依赖实现细节总是好事。
举个例子:工资单类(Payment)中可能包含一些假期数据,比如vacationType(病假、事假还是其它?),日期date(哪天休的假),小时数hours,我们可能会把这些信息提取出来,封装成一个新的类:VacationInfo,然后让Payment直接包含一组VacatonInfo对象。
但Payment类有一个公共方法,addVacationInfo。那么,这个方法的参数该如何设计呢?可以考虑两种方式:
(1)
void addVacationInfo(const VactionInfo& v);
(2)
void addVacationInfo(VacationType type, Date, date, int hours);
如果Vacation是一种更通用的抽象实体,有必要公开给外界,那就应采用第一种;相反,如果它只是一种实现细节,应该隐藏在类或Package实现的内部,那就应采用第二种。
当满足以下两种情况之一时,这种重构是有必要的:
(1)
存在专门针对这些数据的操作;
(2)
还有其它的类或package也包含这些数据。
第一种情况有必要,因为我们不仅提取了数据,也提取了方法。结果就是提取了一个同时拥有状态和行为的对象,而不仅仅是一个数据结构体。这将使原来那个大类的代码显得更加清晰,因为抽象被更好地层次化了。
第二种情况有必要,则仅仅是从代码复用的角度考虑的,抽取出来,大家都可以用,免得每次填加一个相关的新类时就需要从别人那里拷贝一大堆数据成员,也避免了当又有新的数据需要加入到这些成员中时,我们要修改一大堆类。
如果这两个条件都不满足,那么这种重构仅仅能使代码的结构和抽象稍微干净一些,并没有其它重要意义。还是省出时间来干点别的事吧。或者等代码进化到出现以上两种需求时,再重构也不迟。
然后,当我们完成这种重构之后,这些新的小类是否有必要公开给其它的类,以及其它的package呢?这就要看这个新的小类仅仅是这个类(或者这个package)的实现细节,还是一种更通用的抽象实体。
如果是后者,无疑应该公开出来。但如果是前者,那就有必要隐藏它,不让其它类知道。比如在C++语言中,把它定义在某个cpp文件中(而不是头文件中),或者在C#或J***A这样的语言中,把它定义成非公共的类。
但是,如果类的对外接口(“公共方法”,“公共成员函数”)中出现了这种新的类型,该怎么办呢?是不是就没有办法,只能公开了?比如,类有某些get和set方法是专门跟这种小对象打交道的。对于仅仅是实现细节的情况,答案仍然是:隐藏它!宁可让这些接口中出现重构之前的零散数据,也不要出现这种新的类型。因为这样可以减少类或者package之间的耦合。让外界尽量少地依赖实现细节总是好事。
举个例子:工资单类(Payment)中可能包含一些假期数据,比如vacationType(病假、事假还是其它?),日期date(哪天休的假),小时数hours,我们可能会把这些信息提取出来,封装成一个新的类:VacationInfo,然后让Payment直接包含一组VacatonInfo对象。
但Payment类有一个公共方法,addVacationInfo。那么,这个方法的参数该如何设计呢?可以考虑两种方式:
(1)
void addVacationInfo(const VactionInfo& v);
(2)
void addVacationInfo(VacationType type, Date, date, int hours);
如果Vacation是一种更通用的抽象实体,有必要公开给外界,那就应采用第一种;相反,如果它只是一种实现细节,应该隐藏在类或Package实现的内部,那就应采用第二种。
相关文章推荐
- 数据的封装和隐藏原则
- 如何在servlet中将数据封装成JSON格式之后传到前台
- 数据封装相关案例
- 为什么站点实现了https加密之后还是能看到相关数据
- 添加数据成功之后,通过true、false决定是否跳转
- 如何判断mysql中数据表中是否有相关字段——20120412
- 平行x 轴的线段 是否 遮掩 计算几何的扩大数据运算的典型应用,扩大根号2倍之后就避免了小数。 poj 3347 Kadj Squares
- 重构实战-1.原则:有boolean的if else 可将if 和 else 封装为方法。2. 查看传入的Bean用了哪些数据,是否可减少数据。
- 自动拆箱&自动装箱以及String 和基本数据类型封装类生成的对象是否相等
- 封装工具类,判断是否连接网络,请求数据
- 使用ACCESS中隐藏的MSysObjects数据表来确定是否存在某个数据表!
- 前端获取后台数据,前端根据获取的数据判断Repeater列是否显示或隐藏
- JSON相关的,数据彼此间的转化进行了简单地封装,源码如下,支持arc与非arc
- 6.对数组进行排序、求最大值和求元素和的函数采用静态成员函数的方式封装成数组算法类模板ArrayAlg,并采用相关数据进行测试。
- 文件磁盘相关函数[1]-判断文件(包括隐藏文件)是否存在 FileExists
- 前台序列化传过来的值,后台获取之后封装到map当中,让后在转化成json格式,最后在把json里面的参数里面的某一个值进行分割,最后在存到json格式的数据中去。
- wex5中使用password控件,密码可以隐藏,判断输入框是否为空时,无法通过password的.val()方法获取数据
- 为什么站点使用https加密之后还能看到相关数据
- Python编程系列教程第13讲——隐藏数据和封装
- 数据结构:单链表操作之如何判断链表是否带环及相关操作