1. 程式人生 > >裸寫一個含內嵌IE控制元件的視窗

裸寫一個含內嵌IE控制元件的視窗

@溪流
至於躲開的技巧。。。 其實事情起因是這樣。。。
大概08-10年我就在cppblog或者CU(不記得是哪個地方了,又或者都有說)上說interface存在的問題。


一個函式f,它對它的引數有一些要求,例如你的程式碼中不是E_NOTIMPL那些。 而不同的函式對它的引數有不同的需求。

但interface的問題就是,它不能直接描述某函式Fi的需求, 它一定需要一個 **打包** 的過程。

那這個打包的粒度是否恰當,以相信interface是解決問題的方案的人自身的說法, 就看 *設計師(架構師)* 的本事了。
他們還會傳授一些經驗技巧, 比如"每個interface包含3-5個method比較合適"什麼的, 笑死人了。


以我這種不相信interface是解決問題的方案的人來看, 那些展現漂亮的設計的demonstration,也只能在demonstration裡維持它的漂亮。
隨著系統滾大, interface就不能恰如其分的描述出需求。

例如, 就會出現某個函式Fi, 它接受到某個interface Ij, 但它需要interface Ik, 於是就只能 *執行時查詢* , 丟失了靜態型別檢測。

不是 *架構師* 的設計失誤, 而是他要在 *讓每個interface Ij都能儘量恰到好處的描述出它使用者Fk 的需求* 與 *讓總的interface數目維持在一個可接受的範圍內* 之間作一個 *權衡* 。

對實際稍微大一些的系統, 如果想讓demonstration展示出的漂亮設計延續下去, 需要的interface數目就會超出人的接受能力。demonstration演示不出這一點。

這是interface本身的缺陷 —— 需要將一組需求打包(還有其他很多, 先不說了。。。)。 架構師只能緩解, 沒法解決。



對E_NOTIMPL,其實在C++裡還好。。。 因為C++支援多繼承。。。
讓父類提供預設實現, 子類只override需要的便是。。。 而Java那種單繼承就完蛋了。
只是不知道為什麼IOleXXX沒有這樣設計。

對那種需要動態查詢,從interface Ij轉換到Ik的情況,QueryInterface什麼的,真是無能為力。。。



反觀duck typing —— 記得你也用Python的吧 —— 就沒有這樣的限制。
只要實現一個class, 讓它支援那些不是返回E_NOTIMPL的method就完了。
甚至都不需要IOleXXX或者QueryInterface這些概念。
每個函式Fi對它的引數們的要求雖然是 *隱式的*, 但卻是 *精確的*, 不多不少。

脫離Python,更一般的情況來說,要達到"Fi對它的引數的要求*不多不少*, 引數能 *恰如其分* 的實現這些要求"的目標, 並不一定需要 *隱式*, 也不一定需要Python那樣的動態型別。
可以是顯式的、 靜態型別的, 例如Haskell。

使用interface的語言裡,一個型別要實現什麼interface在型別定義的時候就必須決定, 是另一個設計缺陷。 至少在C++/Java/C#裡是這樣。
至於其他的靜態型別的OO語言。。。我學語言有個標準。。。 就是如果這語言強調自己是支援OO的, 那就不學。 所以其他靜態型別的OO語言也不知道。


扯了一大通。。。 其實是想說。。。
我以前只是 *預感* interface的設計在稍微大一點的系統裡就會出問題。
但對使用interface的大的系統都沒有研究的興趣。。。 看著頭就痛。。。 因此說明這問題的 *實際例子* 比較匱乏。。。
於是看到你的文章就有興趣了。。。 "看吧,我果然是對的!" <- 心聲大致是這樣。  
回覆
  更多評論