介面的封裝層次問題
來自專欄 軟體架構設計
介面不但體現在功能上,也體現在其他屬性上(比如性能),所以介面上的可見還是不可見,對於很多人來說,是不清楚的。本文釐清一下這個問題。
介面是一方給另一方提供服務,我們把提供方稱為provider,使用方稱為consumer。比如我們有這麼一個介面:
ouput=provider.service(input)
這是這個介面的功能,把input這個數據轉換成output這個數據,這個數據可以是內存中的數據,可以是設備IO空間寄存器中的值,可以是函數的入口參數,也可以是一個文件。provider和consumer可以是硬體,也可以是軟體。但介面的名,主要還是兩個:input和output(當然,如果你非要算,service本身也是)
當然,其實這背後還隱藏了不少其他名的,比如服務是否具有原子性(多個請求能否被自動排序),(多個不同的請求能否同時執行),連續性(處理髮生異常的時候,如何保證數據的自洽),等等。
但這個不是我們這個討論的重點,我們暫時認為那些概念被埋藏在input和output的外延中了。
provider怎麼處理這個service,這是provider內部被封裝的細節,很多工程師認為,這是「內部現實」,和介面無關。
但考慮一個問題,這個地方在支持某個業務的時候,我們發現這個介面成了我們的性能瓶頸,深入分析我們發現,comsumer提供的input是150個數據為分塊提供給provider的,而provider內部呢,是按100個數據為單位進行整體處理的,這樣一組合,本來可以更高效的流程平白速度降低了。
可能其實comsumer並不在乎這個數據多大,你說好100個數據為單位處理,給你100也不是不行,但你把100封裝起來,這就幫不了你了。
問題是,如果把100暴露出來,provider以後就不好升級了,如果以後處理能力變化了,最優的處理單元是200怎麼辦?provider有很多選擇,一種是暴露一個handle_block的概念,要求comsumer aware這個概念。第二種選擇是引入流的概念(這同時會引入會話的概念),要求comsumer允許數據在provider內部「殘存」,以便provider自己合併流。所以,一旦競爭壓力上來,你認為不會暴露的介面,「自然」會暴露。競爭壓力是一隻無形的手,它最終決定介面的形態,介面不是被設計出來的,它是自然生成的。
介面發展的過程,就好像一個七繞八繞的膠皮水管,一開始都是軟軟的,有的地方彎,有的地方直,但只要衝水,什麼地方會直起來,這是「本身」存在的。
所以,我們設計介面,不能局限在「什麼介面是好介面」這個問題上,而應該看到數據流本身的特性是什麼,基於這個來控制熵增,沒有這個認識,就開始設計複雜的介面形態的,最終只會成為發展的負擔。
推薦閱讀:
※運營還是交付
※雲通訊行業背景下雲片高可用架構演進之道
※複雜軟體系統的簡化方式
※軒轅傳奇引擎架構設計
※氣和深度學習3:回到氣的問題
TAG:軟體架構 |