More C++ Idioms/界面类别
外观
界面类别(Interface Class)
[编辑]目的
[编辑]- 从实作分离出类别的界面。
- 借由执行期间多型(runtime polymorphism)唤起抽象类(abstraction)的成员函数。
别名
[编辑]动机
[编辑]从实作分离出界面类别是好的物件导向设计或程式的基石。对于物件导向程式,分离的主要机制是界面类别。然而, C++(当与Java比较)并没有提供专有的描述这样的分离机制。在Java,关键字interface
用于规定只有抽象的成员函数。 C++ 并没有这样的关键字,但其功能表示接近使用界面类别(Interface Class)惯用语。其想法是只有抽象的成员函数,并且并没有提供任何实作。此外,实作的缺乏指没有实体的界面类别应该被允许。
解决方案与范例程式
[编辑]界面类别只有包含虚拟解构式和纯虚拟函数,因此提供类似于其他语言(例如:Java)界面的构件。界面类别是一个类别规定多型的界面,例如:纯虚拟函数宣告式是父类别。使用类别阶层的程序员可以透过父类别操作,在阶层沟通只能透过类别们的界面。
class shape // 一個介面類別
{
public:
virtual ~shape();
virtual void move_x(int x) = 0;
virtual void move_y(int y) = 0;
virtual void draw() = 0;
//...
};
class line : public shape
{
public:
virtual ~line();
virtual void move_x(int x); // 實作 move_x
virtual void move_y(int y); // 實作 move_y
virtual void draw(); // 實作 draw
private:
point end_point_1, end_point_2;
//...
};
int main (void)
{
std::vector<shape *> shapes;
// 以某種方式塞滿指標向量容器shapes。
for (vector<shape *>::iterator iter (shapes.begin());
iter != shapes.end();
++iter)
{
(*iter)->draw();
}
// 清理指標向量容器shapes。 (一般來說,我將使用智能指標像boost::shared_ptr去自動清理,
// 這邊只是為了解釋)
}
每一个界面类别应该有一个虚拟解构式 。当删除多型指标时,虚拟解构式确保唤起子类别的正确解构式。否则,将有可导致资源泄漏。使用界面类别设计有许多好处:
- 加入新抽象类别
Shape
不会改变程式码,而是取决于界面类别。例如:Square
继承Shape
,然后用自己的方法实作界面虚拟函数。在函数main()
不需要改变。 - 从实作分离出界面类别防止依赖在界面类别的部分程式重新编译。
- 依赖倒转原则(Interface Class,DIP )描述类别实作不应该依赖其他人。反而,他们应该依赖共同抽象类别,此类别可用界面类别所表示。DIP将减少物件导向系统的耦合性。
已知应用
[编辑]几乎所有使用C++好的物件导向软件