深度隔离的界面(从中间类到抽象类)

深度隔离的界面(从中间类到抽象类)

类是对面向过程编程代码中数据与函数的抽象。它将数据与函数封装成类并通过产生的对象类操控数据和函数,使程序员与类对象的数据成员和成员函数打交道,而不必过分关注函数内部的代码和过程。

但是类依然面临着会被修改,一旦类被修改,那么成员函数及数据成员就会被波及(尤其是私有成员,共有成员往往就是界面,供类的使用者的应用程序使用)。而类的生产者就需要将新类提供给类的用户,类的用户拿到新类后放进头文件中,就需要重新编译他们的代码。抽象编程并不彻底,类的生产者并没有与使用者完全隔离开。

采用一种中间类的方法,这种类只有一个私有数据成员,该私有数据成员通过维护一个指向前面提及的向用户提供的类的对象的指针来实现。中间类没有私有的成员函数,只有一批公有成员函数,这批成员函数只是重新实现了前面提及的提供给用户的类的那些公有成员函数,因为这批公有成员函数是用户可以使用的界面函数,在这里重新实现它们的作用和意义与之前完全一样,依旧给客户操纵和使用。

之所以采用中间类,是通过一个指向原有类对象的指针数据成员把原有类的私有成员屏蔽掉,当类的生产者修改了类的私有成员时(一般不修改公有成员,因为那是界面,一旦修改就意味着之前类设计的不完善),都会被这个中间类指针数据成员过滤掉,用户只跟中间类的公有成员打交道从而避免了直接与原有类打交道,原有类的修改不会波及中间类的实现,用户也就不用重新编译他们的代码,从而实现了界面的深度隔离。

但是这个中间类的解决方案依然有不足。这个类是凭空添加的一个类,它除了使用原有类作为它的数据成员外(实际上组合关系),跟原有类没有其它血缘关系。另外在使用的时候还要写这么多的转换成员函数,数量一大,代价也就不小了,也增加了出错的可能。

作为界面,我们希望它越抽象越好,越干净利落越好。所谓抽象,就是尽量不要展现实现细节,只要一个接口就好,所谓干净利落,就是只包含借口(即公有成员,让用户可以随便摸,随便用的成员),不要将一些私有的用户不用碰的成员放在界面上。

非常幸运的是抽象类正式我们要找的这样的类,因为抽象,它可以提供纯虚函数,不牵扯成员函数定义的细节,不提供任何私有数据,干净又利落。

 另外,因为抽象类是类层次结构的基类,那些成员函数的定义以及私有成员就留给抽象类的继承子类们去做吧,它们可以千变万化地去做,而子类们的千变万化的类对象又如何通过基类来与用户取得联系呢?没关系,不要忘了,还有多态呢!用户只要使用抽象类提供的公共成员界面,把自己要处理的对象传给这些界面上的函数,至于它们内部实际调用的是哪个子类的成员实现,就让多态自己去考虑吧!

由于抽象类没有对象,所以抽象类也就没有构造函数,那么客户既然只能跟抽象类打交道,它们有如何利用抽象类创建对象呢?没有关系,我们在抽象类中增加一个形如下面的函数来获得子类对象,

Base_class& createSub_class(…)

{

Return *new Sub_class(…)

}

可以看出这个成员函数返回一个抽象类对象指针即基类指针,但它的实现部分则是调用了继承子类的构造函数,创建了一个子类对象,并返回了这个对象的指针到抽象类的指针上去。这个函数在抽象类外声明并连同抽象类一起提供给客户,可以重载以满足不同方式创建子类对象。但它的实现一定不能放在抽象类中,而是放在相应的子类类定义外面成为子类的不可分割附带部分封装起来。这样一来通过利用抽象类的特征和多态这一性能,成功地将类的生产者与用户作了完美地深度隔离。从此,用户们再也不知道类的生产者是如何实现类的细节,如何实现问题的解决方案了。而他们只需要关注属于自己的那块问题就可以了,别人提供的组件就直接拿过来用吧,这块出了问题怎么也怪不到他们头上来了。

 

 

(原创博文,转载请注明出处)

你可能感兴趣的:(编程,Class)