首頁 > 娛樂

微機介面技術是什麼?微機介面技術是什麼?微機介面是什麼型別的?

由 SingWing 發表于 娛樂2021-05-26

簡介如果“面”、“角色”、“職責”等是我們現實世界中物件關係的描述,那麼“介面”就是這種物件關係在計算機世界中的抽象

微機介面技術是什麼

前言

在計算機領域,介面與堆疊一樣是一個異常重要的概念。計算機語言中也通常會有相應的抽象,比如Java 和 C# 中都可以用面向物件的方式定義介面。儘管我們一直都在用,但還沒有提高到與面向物件同等重要的級別,甚至我們只是將其看作是面向物件的一個方面。

我們都知道介面在計算機語言中的語法和語義,所以我並不打算再次詳細重複這些定義,而是試圖脫離語言環境,從我們身處的這個世界中進行一番分析和闡述,然後再映射回語言中,以便有可能幫助人們更直觀地理解和使用介面。不過,在開始之前,我們還是先回顧一下在計算機語言中介面的基本定義。

語言中的介面

在計算機語言中,介面通常具有如下的特性:

不包含例項欄位。

包含方法、屬性、索引器和事件等行為,且通常都是公共的。

在單繼承語言中,一個類不可以繼承多個基類,但可以同時實現多個介面。

介面不能被例項化。

介面之間可以繼承。

當然,隨著語言的發展,介面也在進化。比如介面可以提供預設實現,可以包含靜態或常量欄位,可以包含巢狀型別等。不過這些進化並沒有改變介面的基本含義。我們在這裡不做詳細的展開。

物件都具有多面性

我們每一個人都具有多面性

。在父母面前,我們是孩子。在孩子面前,我們是父母。在老公/老婆面前,我們是老婆/老公。在老師面前,我們是學生或家長。在醫生面前,我們是病人或家屬。在理髮師Tony面前,我們是理髮的客戶。在地獄油鍋面前,我們是天婦羅的原料。在天使面前,我們是吃天婦羅的呆子。我們稱自己為程式猿。但在專案經理面前,我們是研發。在老闆面前,我們是員工。在客戶面前,我們是龔工或周工。到了朋友那裡,我們又是修電腦的。

我們的每一面都對應了一種或一組交流方式

。在父母面前,我們可以撒嬌,可以衣來伸手飯來張口。但是我們肯定不能將對父母的撒嬌用在老師身上,除非你的父母同時也是你的老師。同樣是撒嬌,對男朋友的撒嬌和對父母的撒嬌又是不同的。

有許多“面”,我們是同時具有的

。我們可以同時是孩子和家長,可以同時是學生和老師,可以同時是醫生和病人。還可以同時是病人和老師,可以同時是Tony和男朋友。也有一些正常情況下不會兼具的,比如一般不會同時是老公和老婆,正常邏輯下也不會同時在地獄油鍋中翻滾和在天堂裡發呆。

我們的每一面都意味著一種能力、職責或角色。

外部的人可以透過我們的某一個面或某幾個面與我們交流。比如,具有老師角色的人,可能會透過我們的學生面或家長面與我們交流。具有醫生角色的人,會透過我們的病人面或家屬面與我們交流。而Tony在給我們理髮的同時,可能正琢磨著怎麼透過自己的“銷售”角色向我們推銷699的套餐,或惦記著下班後怎麼透過“男朋友”這個角色跟妹子去哪家餐廳。

一種角色都會包含一組行為

。作為學生,最主要的行為是學習和做作業,當然還會有考試這種噩夢級的行為。作為老師,主要行為是上課和佈置作業,對應的還有批改作業和閱卷等行為。作為醫生,主要行為是治療,當然也會有研究這種行為。同時,醫生還可能帶研究生,所以同時兼具醫生和老師這兩個角色中的行為能力。

成為一種角色,或具有某種能力,通常是需要付出成本的。比如成為醫生,可能要經過5年本科和3年碩士的煎熬。成為Tony則要去藍翔深造。

我們的一個方面,在外部會存在對應的其他人身上的另一個方面

。比如我們的學生面與其他人的老師面之間,醫生面和病人面之間,父母和孩子之間等等。這對應的兩個面之間形成了一種契約關係。潛在的,一個具有老師面的人,能夠與所有具有學生面的人構成教學關係,而不論Ta的年齡、性別、高矮、胖瘦等。一個具有醫生面的人,能夠與所有具有病人面的人構成醫療關係,而不管Ta的出身、籍貫、人種、職業等。契約關係的兩個面,少了任何一個,都會讓另一個變得沒有意義。

即便人與物,或其他物件之間也是如此。我們開的汽車,對我們來說它的主要職責是運輸。單從運輸的角度,我們並不需要關心它的材質,也不需要關心製造工藝和流程。這些方面,是製造工人在製造過程中要關心的。對於流浪的貓咪來說,汽車可以遮風擋雨,引擎的餘溫可以溫暖身體。你看,汽車也具有多面性。

什麼是介面?

這裡的“面”就是介面(interface,interactive+face)。如果“面”、“角色”、“職責”等是我們現實世界中物件關係的描述,那麼“介面”就是這種物件關係在計算機世界中的抽象。當然,物件之間不是隻具有介面關係。這一點我將在下文中進行說明。

我們聽到過許多關於介面的定義或理解,本文中的定義也是這些理解中的一種。有許多是在計算機科學範疇內的定義,看上去有些晦澀。我試圖跳出這個範疇,將其定義為:

介面是物件為行使一種職責而與外界互動時,從外部看到的一組相關行為的集合

。彙總一下前文的例子,用一個看上去不太恰當,但確實可以協助表述其意義的俗語描述就是:介面能夠讓我們“見人說人話,見鬼說鬼話”。或者說,介面讓我們每一個人都具有“多面性”。

對照前面的示例,我們總結一下介面應該具有的普遍特性:

1、 介面是一個物件對外互動用的。如果一個物件不需要跟外部進行互動,那麼這個物件就不需要任何介面。或者說,如果一個物件沒有定義任何介面,那麼這個物件將無法與外部進行任何互動。我們無法想象這樣的物件有什麼存在意義,事實上,根本無法感受到這種物件的存在。所以,對個體而言,介面總是呈現出“對外”的特性。當然,這個“外部”可以是有範圍的,最大的範圍就是public。

2、 “互動”這個詞意味著,介面中通常只包含行為,即介面通常只關心行為。與物件個體生存相關的內部表示,介面大多並不關心。甚至該物件個體是否存活也不被關心。如果讓計算機單純從理髮關係上模擬理髮師和顧客,那麼Tony是不會關心構成顧客生命個體的心肺等各種身體引數的,甚至不關心某一位顧客是否存活。理髮師存在的意義是,世界上有需要理髮的顧客,具體是誰,是不需要關心的。所以,定義介面時,我們不會定義與個體例項相關的內部欄位。當然,在一些特殊情況下,我們需要暴露一些引數。比如醫生可能需要知道某個器官的引數,但一般不會是透過將器官直接血淋淋展現給醫生的方式,而是透過某種手段“獲取”屬性值。

3、 一個物件可以實現多個介面。這是物件多面性的根本。每多一個介面,就意味著物件多一種能力或職責,使得它能夠與外部構成契約關係的其他物件進行互動。

4、 角色或職責等是一種類別的概念,是行為規範的集合,顯然,它是不能被例項化的。

現在,回頭看看計算機語言中的介面。相對來說,比起直接閱讀規則化的介面語言規範可能要容易理解一些。比如:為什麼介面不包含欄位?為什麼介面上只包含行為?為什麼介面的例項成員不會是私有的?為什麼一個物件可以實現多個介面?為什麼許多介面使用類似 Convertible、Disposable這樣以“ble”表達動作和能力的方式命名?

面向物件與介面

面向物件有三大特徵:封裝、繼承和多型。這三個特徵並沒有(很好地)概括或表達介面的概念。面向物件描述或抽象了現實世界中物件之間類別(class)的關係,這種關係是一種靜態的關係。比如,生物分為動物和植物,動物中包含人類和鳥類。人類分為男人和女人。還可以說人類分為嬰兒、少年、青年、中年和老年。看上去,這些關係是在某一個層級上,為滿足某種需求,透過某種或某些性質或行為對類別進行的進一步劃分。這種劃分使得我們更容易理解、學習、專注和管理,從而更容易在計算機中進行建模。即便是行為,在面向物件中,我們關注的也是行為之間的繼承以及多樣化,也就是父類和子類之間行為的差異,而不是它們之間的互動。

但是介面不同。它描述了一個物件在某一方面的能力、職責或角色,透過這種能力、職責或角色,外部其他物件可以與它進行什麼樣的互動,以及如何進行互動,這是我們所關心的。彼此互動的物件之間可以沒有面向物件的級別關係。因此,介面實際上是定義了物件之間的一種動態關係。

我們甚至應該提出並全面研究“面向介面”這種方法,比如“極端地”建立一種面向介面的語言,並要求所有的行為都必須透過介面實現。然後,將面向物件(OO:Object Oriented)方法和麵向介面(IO:Interface Oriented)方法結合使用,形成OIO(Object &Interface Oriented)方法。當兩者結合時,面向物件中人們發現的一些問題就有可能得到解決,讓人頭大的設計模式中的各種原則可能也更容易理清。

比如單一職責原則。我們很難僅在面向物件這個上下文中要求一個類只有一個職責,在開發實踐中我們通常也不容易這麼做。因為,這不是我們世界的真實樣子,多面性才是它的真正面貌。而對於我們人類來說,許多場景都要求我們“八面玲瓏”,情商要高。貌似程式猿們經常被這麼教育來著。

但是,如果是在介面上實施單一職責就非常自然,非常容易理解了。這就是為什麼,介面通常(應該)只有一個或寥寥數個方法。比如IDisposable只有一個方法Dispose。儘管IConvertible有不少方法,但是它也只關心資料型別和轉換,理論上可以合併為一個。

再比如介面不變性以及擴充套件之間的矛盾也就很容易透過介面繼承等解決了。因為,我們確實很難僅在面向物件的框架下解決這個問題。萬事萬物時時刻刻都在變化,才是不變的真理。怎麼能夠要求一個物件不變呢?怎麼能夠期望使用者需求不變呢?

單純的面向物件並不能很好地模擬現實世界。這是迄今為止,在使用面向物件方法時,有時候會覺得混亂的主要原因之一。不過,OO和IO的結合將可能極大地改觀這種狀況。

面向過程與介面

事實上,函式就是一類介面,它定義了呼叫方和被呼叫方的契約關係。面向過程(Procedure Oriented)的方法是從函式的角度來為物件之間動態關係建模的,這與介面是完全一致的。適用於介面的設計原則同樣適用於函式。

因此,面向過程的方法是一種面向介面的方法。單純的面向過程同樣不能很好地模擬我們的現實世界。對於面向過程的研究,應該提高到介面這個層次上,而不是僅僅侷限於傳統的“狹義函式”。之所以稱其為“狹義函式”,是因為我將CPU指令以及老闆購買我們的某種能力賺取利潤也看作是函式,或者稱為“廣義函式”。這個廣義函式就是介面。

介面與許可權

“歷史上”有許多人跟我探討過許可權的問題,這實際上也是設計模式等相關的一類問題。大體上,許可權可以分為兩類:一個是資料許可權,另一個是功能許可權。

資料許可權是指一個人或一類人對某一資料是否擁有訪問許可權,擁有何種訪問許可權。比如在Windows、macOS或Linux上,一個使用者是否有權檢視一個檔案,或是否有權修改一個檔案的內容或刪除該檔案。在資料庫訂單表中,我們必須驗證當前使用者是不是一個訂單的下單使用者,以防止訂單被其他使用者檢視、修改或刪除,也就是所有權的問題。

功能許可權是指一個人或一類人是否能夠執行某個或某些功能。對於一個電商系統,所有的匿名使用者都可以註冊、登入,所有的登入使用者都可以登出、下單、檢視訂單和支付等。而在一個企業資訊化系統中,對同一個資料(比如人員工資單),經理與財務可能使用不同的功能檢視或管理。這些功能可能體現為一個或多個頁面,一個或多個API呼叫(透過HTTP、RPC等協議)。儘管對資料的許可權有時候可以透過功能許可權實現,但資料許可權的管理通常仍然不可或缺,比如上述的訂單所有權的例子中。對許可權的問題,我們不做過多闡述。單純來看這個功能許可權。

一些開發團隊會在功能頁面上,透過區分當前使用者的角色來實施許可權控制,例如控制某個按鈕或選單顯示或隱藏。我不太認同這種方式。這會讓頁面的邏輯變得非常複雜,難以維護。而且這種方式可能並沒有從根本上解決許可權的問題,它只是對終端使用者隱藏了入口。在過去使用JSP、ASPX等開發的應用系統中,JS、CSS、HTML、Java、C#等各種語言混雜,再加上按角色判斷時的各種分支,可以想象軟體質量會如何,開發和維護人員的難度會有多大。

還有一種辦法就是,將相關的功能封裝為模組,然後按模組進行授權。仔細分析一下,不難發現,這種模型跟介面模型是一致的。一個模組就是一個介面,一個功能就是一個行為。模組跟介面一樣,表達了資料或應用系統的一種能力或職責,只有契約關係另一端相應角色的使用者才能透過這個介面,與資料或應用系統進行互動。這樣,對許可權的管理就變成了對“模組介面”和“使用者角色”關係的管理。

圍繞這種關係的兩個方面,軟體開發就可以分為兩種基本模式:一種是以業務模組為中心,一種是以使用者為中心。過去主要是以業務模組為中心,使用者次之。老一輩評審專家們特別喜歡業務功能模組的層次結構圖。現在則開始以使用者為中心,遵循以人為本的原則。相對於傳統軟體行業,網際網路行業是以使用者為中心的典範。

當把模組和介面這樣對映時,如果我們把面向介面(IO)中的單一職責、隔離、耦合等原則(設計模式原則)應用於模組設計和許可權管理,那麼我們的應用系統,想不是高內聚、低耦合的都不容易,對應的許可權管理系統也就可以非常自然和簡潔。

後語

軟體開發工作是一種創造性的工作,也是一種翻譯性的工作。創造,體現在將現實世界中的事物以及關係在計算機世界中進行建模。翻譯,體現在用語言將模型編譯為產品,以便終端使用者能夠與計算機世界相互溝通和交流。這兩個過程分別就是

設計

實現

面向物件是現實世界到計算機世界的一種抽象方法,它在幫助我們建立物件之間的靜態關係上立下了汗馬功勞。而介面則是物件之間動態互動關係在計算機世界中的抽象,並在計算機軟硬體中廣泛使用,包括:硬體介面、使用者介面(UI)、以及語言中的函式和介面等。

透過重新認識和反思現實世界中事物之間的動態關係和靜態關係,然後對映到計算機世界中,就有可能幫助我們更好的理解介面和麵向物件等相關的概念。

希望這篇文章可以幫助大家更好地理解和使用介面。

理解計算機語言中的介面

Tags:介面我們物件面向物件許可權