C++接口总是空的,或者虚的,C++接口和C++抽象类代表的就是抽象类型,就是我们需要提出的抽象层的具体表现,它不实现任何东西,所以可以有以下的结论:
定理1:C++接口是依赖的终点。接口不需要依赖任何东西。
推论1:依赖C++接口是安全的。不会带来更多的依赖关系。
推论2:当我们需要依赖时,我们必须尽量做到:我们依赖的是接口。而不是实际的东西。
前面的WNS的例子中,是函数指针接口的应用。下面举出一个纯虚类的例子。
假设我们制作了一个对话框(MyDlg)。我在对话框上添加了一个控件(MyCtrl)。MyCtrl派生于一个基类MyCtrlBase,该Base类有一个虚函数:
- virtual void OnClick() = 0;
该控件被点击的时候,则OnClick会被调用。现在的意图是,该控件被点击的时候,我的对话框发生某种变化,比如说,MyDlg::OnMyCtrlClick()被调用。这如何实现呢? 最常见的但是也是错误的方法如下首先是MyDlg:
- class MyDlg : public MyDlgBase
- {
- public virtual void OnMyCtrlClick()
- { … }
- private: MyCtrl * m_myCtrl;
- class MyCtrl : public MyCtrlBase
- { public: virtual void OnClick();
- private:
- MyDlgCtrl *m_parentDlg; };
我确实实现了。但是这个实现方法真的很愚蠢。因为MyCtrl和MyDlg完全依赖了对方。任何一个都不能脱离对方而被重用。MyDlg依赖MyCtrl尚可以理解。因为这个对话框中含有这个控件。但是MyCtrl为何要依赖MyDlg呢?这是完全没有必要的。我自己是一个控件,没有理由理会我在哪个窗口里。
无论在哪个窗口里,都是一样的作用。 当对话框上有多个不同控件时,情况会更加复杂。最终的结果,导致全部的组件之间都互相依赖,没有任何一个部分是可以重用的。 正确的方法是抽象出一个接口。这个C++接口叫做“点击接收者”。#t#
下面再举我们在Capsuit的开发中,碰到的一个问题。情况是这样的:我们的软件,要对计算机进行全面的检查。包括检查硬件,检查操作系统信息,检查注册表,检查进程,以及运行的服务等等,来判断当前计算机是否正常。
本人负责开发检查部分。这个部分的任务是,根据外部输入的需求,来调用相应的实际进行检查的函数。这些函数则由各个不同部门的同仁实现好。本人只要调用他们就可以了。
- struct condition { string check_type; // 告诉我检查的类型, string param1;
- // 检查的参数,比如说是哪个注册表项要检查,等等 string param2;
- // 同上,都是取决于不同类型的检查而不同的参数 };