您的位置:首页 > 其它

相关数据是否封装/封装之后是否隐藏

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实现的内部,那就应采用第二种。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐