SDK的接口設(shè)計與規(guī)范

在SDK開發(fā)中,接口(全稱應用程序接口,也就是大家熟知的API)是很重要的一塊,它是SDK與上層應用程序之間進行交互的橋梁,接口規(guī)范是確保接口的一致性、完整性和可維護性的重要手段。

為了保證接口的可讀性和可維護性,在接口設(shè)計的時候就需要遵循一定的原則和規(guī)范,如接口命名的原則、接口設(shè)計的原則、接口的版本管理等。

1. 接口命名的原則

1.1. 一致性

一致性是指在整個SDK接口中保持命名的一致性,包括:風格的一致性和術(shù)語的一致性。

命名風格一致

在整個SDK中,接口命名應采用一致的風格,例如駝峰命名法、下劃線命名法等。

命名術(shù)語一致

使用統(tǒng)一的術(shù)語來描述相似的功能或概念,避免在不同接口中使用不同的術(shù)語。

  1. 相近的詞匯只用一種: 舉一個例子,要表示“目錄”的概念,catalogoutline都可以。但不能在A接口了用catalog(如openCatalog),B接口里用outline(如closeOutline),這一種錯誤的命名方法。正確的命名是:要么全部用catalog(openCatalog、closeCatalog),要么全部用outline(openOutline、closeOutline)。

  2. 相反的詞匯要成對出現(xiàn): 如使用了begin表示開始,則要使用end表示結(jié)束,而不應該用stop;同樣的,如果使用了start就應該用stop。在實際項目中見到最常見的錯誤混用是startend,這種命名其實是不太優(yōu)雅的。程序員開發(fā)中常見的成對出現(xiàn)的單詞可以參見《附錄A-計算機術(shù)語中成對出現(xiàn)的單詞》。

前綴和后綴一致

如果某些接口具有特定的前綴或后綴,應在整個SDK中保持一致。

舉例來說,如果某些接口需要使用前綴來表示其功能,例如create、get等,那么這些前綴應在整個SDK中保持一致。例如,創(chuàng)建用戶接口可以命名為createUser,創(chuàng)建文件文件接口命名為createFile;獲取用戶接口可以命名為getUser,獲取文件的接口命名為getFile。

命名空間一致

相同模塊的接口采用相同的命名空間,且如果加了命名空間,那么該模塊下的所有接口都需要加上命名空間。不能部分接口加命名空間,部分接口不加。

對于C++的SDK,通常整個SDK會使用一個相同的命名空間,如:cutl表示C++通用工具庫的命名空間。當然如何SDK比較復雜,包含多個大的模塊,也可以使用二級命名空間,如:cutl::fs表示文件系統(tǒng)模塊的命名空間,cutl::time表示時間處理模塊的命名空間。STL就有這種典型的應用,如:std::chrono。

版本一致

在接口版本更新時,已有的接口,接口名必須保持一致。這樣我們的接口才能保持向后兼容。

舉個例子,我們有一個接口用于展示文本信息,這個接口v1.0的版本只支持純文本的展示,接口定義如下:

void showText(const std::string& text);

后面需求變更了:不僅要支持純文本的展示,還要支持HTML格式的展示和Json格式的展示。這個時候,為了保證我們接口的向后兼容性,V2.0的接口可以這么定義:

enum TextFormat {
    TEXT,
    HTML,
    JSON
};

void showText(const std::string& text, TextFormat format = TextFormat::TEXT);

這里增加一個format參數(shù),可以拓展新增的格式。因為format提供了與V1.0版本含義一致的默認值,且接口名保持不變,所以這個接口能夠做到向后兼容。

1.2. 簡潔性

命名應簡潔明了,避免冗長的命名,確保接口名稱直擊接口的核心功能。

避免冗余

例如,getUsergetUserFromDatabase更簡潔。

使用縮寫

可以通過適當?shù)目s寫來簡化接口的名稱。如getUserInformation可以縮寫成getUserInfo。但使用縮寫時,需要遵循以下幾個原則:

  1. 專業(yè)術(shù)語中的專用書寫,如iddns。
  2. 要是程序員中大家普遍熟悉的縮寫。如num表示number。
  3. 縮寫要可發(fā)音方,方便開發(fā)人員進行交流。如表示“當前時間(currentTime)”的縮寫用curTime, 而不是crtTime(crt無法發(fā)音,只能念字母c、rt,而且容易與CRT(C RunTime)術(shù)語混淆)。

程序開發(fā)中常見的縮寫,可以參見《附錄B: 計算機術(shù)語中常見的單詞縮寫

1.3. 描述性

接口名應能準確的描述其功能或用途。通常用兩種方式來命名我們的接口:

  1. 名詞: 常用于獲取信息或展示信息的接口,如userList表示用戶列表,fileManager表示文件管理器。
  2. 動詞+名詞: 常用于表示執(zhí)行某項操作,如createFile表示創(chuàng)建文件、openFile表示打開文件、closeFile表示關(guān)閉文件。

2. 常見的命名法

2.1. 駝峰命名法

駝峰命令法(Camel) 是指混合使用大小寫字母來構(gòu)成變量和函數(shù)的名字,當變量名或函數(shù)名是由一個或多個單詞連結(jié)在一起構(gòu)成的唯一識別字時,第一個單詞以小寫字母開始,從第二個單詞開始以后的每個單詞的首字母都采用大寫字母。如:createFile、openFile,這樣的變量名看上去就像駱駝峰一樣此起彼伏,因此被稱為駝峰命名法。

Java/Objective-C/Swift語言默認就是使用駝峰命名法。

2.2. 帕斯卡命名法

帕斯卡命名(Pascal) 也叫大駝峰法,與駝峰命名法類似,不過駱駝命名法是首字母小寫,而帕斯卡命名法是首字母大寫,如:CreateFileOpenFile。

2.3. 匈牙利命名法

匈牙利命名法通過在變量名前面加上相應的小寫字母的符號標識作為前綴,標識出變量的作用域,類型等,命名的格式如:[屬性]_[類型(小寫)][變量名(首字符大寫)],如m_nAgem_表示該變量是成員變量,n表示該變量是整型;nAge表示局部變量,類型為整型。表示數(shù)據(jù)類型的前綴符號也可以多個同時使用,如m_lpszStr表示指向一個以\0字符結(jié)尾的字符串的長指針成員變量。

屬性:

  • g_: 全局變量
  • m_: 類成員變量
  • s_: 靜態(tài)變量
  • c_: 常量

類型:

  • a : 數(shù)組(Array)
  • b : 布爾值(Boolean)
  • by : 字節(jié)(Byte)
  • c : 有符號字符(Char)
  • cb : 無符號字符(Char Byte,并沒有神馬人用的)
  • cr : 顏色參考值(Color Ref)
  • cx,cy : 坐標差(長度 Short Int)
  • dw : 雙字(Double Word)
  • fn : 函數(shù)(Function)
  • h : Handle(句柄)
  • i : 整形(Int)
  • l : 長整型(Long Int)
  • lp : 長指針(Long Pointer)
  • n : 短整型(Short Int)
  • np : 近程指針(Near Pointer)
  • p : 指針(Pointer)
  • s : 字符串(String)
  • sz : 以 Null 做結(jié)尾的字符串型(String with Zero End)
  • w : 字(Word)

匈牙利命名法起源于微軟的內(nèi)部,微軟的C++項目用的比較多。但因其規(guī)則的復雜和臃腫,現(xiàn)在這種命名法在逐步被淘汰,新的項目越來越少用這種命名法了。

2.4. 下劃線命名法

下劃線命名法將多個單詞的變量用下劃線(_)進行分割,單詞本身全部用小寫,如create_file、open_file。

3. 接口設(shè)計原則

3.1. 三大原則

面向?qū)ο笤O(shè)計中有五大基本的原則,他就是SOLID原則,是五大原則首字符的搜寫。

  • S 單一職責原則
  • O 開發(fā)關(guān)閉原則
  • L 里氏替換原則
  • I 接口隔離原則
  • D 依賴倒置原則

這里其中有三大原則同樣適用于API接口的設(shè)計。他們分別是:

單一職責原則

單一職責原則(Single Responsibility Principle),簡稱SRP。每個接口應該只有一個明確的目的和職責。這樣可以確保接口的簡潔性和高內(nèi)聚性,避免接口功能過于復雜和冗余。

接口隔離原則

接口隔離原則(Interface Segregation Principle), 簡稱ISP。一個接口不應該定義太多的功能,只提供這個接口必要和相關(guān)的功能,應用層不應該依賴它不需要的接口。接口應該被拆分成更小的、更具體的部分,以減少對未使用方法的依賴。

依賴倒置原則

依賴倒置原則(Dependence Inversion Principle), 簡稱DIP。應用層模塊不應依賴于低層模塊的具體實現(xiàn),而是依賴于抽象,即接口。所有我們的SDK應該只提供接口與應用層進行交互,而不應該暴露具體的實現(xiàn)。

3.2. 版本管理與向后兼容

除了上面的三大原則外,還有兩點需要注意:SDK的版本管理和向后兼容。

3.2.1. 版本管理

版本管理: 是說SDK必須要有版本號,并提供獲取版本號的接口(如:getVerstion()),每次發(fā)布SDK時,必須保證版本號增量遞增。這樣上層應用就可以進行一些邏輯的判斷,如:判斷某個特定的接口是從哪個版本開始支持的。

3.2.2. 向后兼容

向后兼容是說SDK的每一次發(fā)版,所有接口都必須兼容低版本。要做到向后兼容,就必須遵循一個原則:

接口只能新增和修改,不能刪除。

新增: 這個不需要解釋,肯定不會有兼容性的問題。

刪除: 對于已經(jīng)發(fā)布的接口,即使你想廢棄,也不能直接刪除,只能在接口的注釋里打標簽,如:@deprecated,表明此接口已廢棄,后期將不再維護,上層應用應該盡快用新的接口替代。

修改: 也需要保證修改后的接口與修改前的接口兼容,如何做到這一點呢?可以有兩種策略:

  • 接口的名稱、入?yún)⒑统鰠⒍急3植蛔儯恍薷慕涌诘木唧w實現(xiàn)。
  • 新增參數(shù)但提供默認值,且默認值的行為與舊版本保持一致。這個在 “1.1 一致性” 小節(jié)的 版本一致 中有舉例,這里不再贅述。

4. 完整的注釋

對于需要對外開放的SDK,每一個接口都需要有完整的注釋。這樣調(diào)用方才能更具體的了解每個接口的功能和用法。關(guān)于接口注釋更詳細的介紹,將會在下一章進行講解。

歷史文章推薦:

01. 什么是SDK

02. SDK的設(shè)計目標

03. 接口設(shè)計與規(guī)范

04. 接口注釋與接口文檔

05. 原理篇:字符集與字符編碼(一)

06. 原理篇:字符集與字符編碼(二)

07. 原理篇:多字節(jié)字符與寬字節(jié)字符

08. 原理篇:靜態(tài)庫、動態(tài)庫與運行庫

附錄A-計算機術(shù)語中成對出現(xiàn)的單詞

附錄B: 計算機術(shù)語中常見的單詞縮寫


大家好,我是陌塵。

IT從業(yè)10年+, 北漂過也深漂過,目前暫定居于杭州,未來不知還會飄向何方。

搞了8年C++,也干過2年前端;用Python寫過書,也玩過一點PHP,未來還會折騰更多東西,不死不休。

感謝大家的關(guān)注,期待與你一起成長。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容