by Yazy -- 2005,04.21
構件、高級面對象的核心是:通過已經編繹代碼,生成對象,該對象與源代
碼的定義具有完全一致的語意。這樣一種創建對象的能力降低了組件複用的
複雜性。(我這裏所用的“高級”是指“具有運行時特性的”)。
比如一個使用C++語言定義的類:
class Widget
{
private:
int _number;
string _name;
public:
Widget(int number, const string& name)
: _number(number), _name(name) {}
int getNumber()
{
return _number;
}
const string& getName()
{
return _name;
}
};
如果將其發佈爲二進制組件(如DLL),那麼要通過該二進制組件創建 Widget
的一個實例的話,我們必須要知道 Widget 類的聲明纔可以做到。亦即,如果
要複用一個二進制組件(如DLL)裏的對象,我們必須要清楚地知道該對象的
原始結構。如果是C++語言,我們可以使用 C/C++ 的頭文件來描述 DLL 文件裏
類型的結構,配合頭文件與 DLL 文件可在新的 C++ 源代碼裏創建對象。
但是頭文件始終是 C++ 源程序的一部分,而且對於創建類型的對象來說還是很
累贅。重要的是這種複用二進制組件的方式還是靜態完成的,即在源代碼編繹
之時完成的。
高級的面向對象更希望的是在程序運行之時,可以創建一個二進制組件裏的類
型,這種創建過程不需要編繹器或者最好不需要第三方工具的參與,更加不需
要“頭文件”這樣累贅文件。
C++的抽象數據類型沒辦法進行自描述,其語義需要其聲明代碼來描述,而且這
些描述只在源代碼中有效,源代碼編繹之後,其抽象數據類型的語義便不復存
在。所以在新的 C++ 源代碼裏使用一個 DLL 文件裏的類型時,必須使用頭文
件附上該類型的聲明,如此纔可以創建類型的實例。
所以“C++的面向對象特性只在編繹時期有效”。原因便是C++的 class 沒辦法
進行自描述。這種自描述特性要求類的一個實例在運行時可以被認識到其語義,
即運行時代碼可以通過某個對象或者其引用掌握到該對象的類的所有信息,即“
該對象是由什麼類創建的”(這有別於“通過二進制組件創建類型的實例”)。
在COM中類的語義信息通過接口定義語言描述,程序編繹時將這些描述附到 DLL
文件或者其它一些共享區域(如註冊表)當中,我們可以通過這些信息來創建
DLL裏類型的實例。.NET運行庫使用“元數據(Meta Data)”來描述這些信息。
這些描述信息的作用相當於下面的一個聲明,它可以用於描述一個DLL中Widget
的語義:
class Widget
{
private:
int _number;
string _string;
public:
Widget(int, const string&);
int getNumber();
const string& getName();
};
.NET的“元數據”還支持運行時對象的類型識別,不知COM、DCOM、COM+是否支
持,或者其它標準,如CORBAR、SOM支持不?有待學習……