API設(shè)計(jì)的一些核心原則

沒(méi)有經(jīng)過(guò)設(shè)計(jì)的代碼,是沒(méi)有靈魂的。


魯迅沒(méi)說(shuō)過(guò)這句話

設(shè)計(jì)涵蓋的內(nèi)容很廣坤按,而API設(shè)計(jì)是與日常開(kāi)發(fā)關(guān)系比較緊密的一塊。換句話說(shuō)呀非,掌握了一些核心的設(shè)計(jì)要領(lǐng),對(duì)代碼質(zhì)量提升是立竿見(jiàn)影的。

無(wú)規(guī)矩不成方圓岸裙,API設(shè)計(jì)一樣猖败。最近學(xué)習(xí)了Google工程師總結(jié)的API設(shè)計(jì)原則,看完后降允,腦海中回憶起自己寫(xiě)的代碼恩闻,方法的命名、參數(shù)順序剧董、異常處置幢尚、功能范圍,無(wú)一不被作者所戳中翅楼。我覺(jué)得很有價(jià)值尉剩,所以拿來(lái)與大家一起分享,相信對(duì)你肯定有幫助毅臊。當(dāng)然理茎,作者總結(jié)的比較簡(jiǎn)潔,具體含義褂微,需要大家思考并深入的體會(huì)功蜓,相信經(jīng)過(guò)一番思考以后,定有收獲宠蚂。

由于原文是生肉,為了給部分小伙伴提供一些便利童社,我進(jìn)行了翻譯求厕,翻譯不好的地方還請(qǐng)指正,在此表示感謝扰楼。當(dāng)然有喜歡生肉的同學(xué)呀癣,我也會(huì)在文末評(píng)論處貼上原文地址,請(qǐng)自取弦赖。

以下是正文部分项栏。


image

API設(shè)計(jì)原則

通用原則

api應(yīng)該只做一件事,并且要做好

  • 功能應(yīng)易于解釋
  • 如果很難對(duì)一個(gè)功能命名蹬竖,通常是一個(gè)壞兆頭
  • 好名稱驅(qū)動(dòng)開(kāi)發(fā)
  • 模塊能夠拆分和合并

最小化內(nèi)容訪問(wèn)權(quán)限

  • 類和成員變量盡可能私有化
  • 公共類不應(yīng)該有公共變量(常量除外)
  • 最大化信息隱藏
  • 允許模塊能夠獨(dú)立的使用沼沈、理解、構(gòu)建币厕、測(cè)試列另、調(diào)試

名字很重要 -api是一種小語(yǔ)言

  • 命名在很大程度上應(yīng)該是不言自明的(避免過(guò)于隱晦的縮寫(xiě))
  • 保持一致,同一個(gè)詞應(yīng)該始終代表一個(gè)含義(在整個(gè)api旦装、跨平臺(tái)的api)
  • 保持規(guī)律性-力求對(duì)稱
  • 代碼應(yīng)該讀起來(lái)像散文页衙,如:
if (car.speed() > 2 * SPEED_LIMIT){
    generateAlert("Watch out for cops!);
}

文檔很重要

重用是一種說(shuō)起來(lái)容易做起來(lái)難的事情。要做到這一點(diǎn),需要良好的設(shè)計(jì)和非常好的文檔店乐。即使當(dāng)我們看到良好的設(shè)計(jì)(這仍然是不常見(jiàn)的)時(shí)艰躺,如果沒(méi)有良好的文檔,我們也不會(huì)看到組件被重用眨八。
- D. L. Parnas, _Software Aging.
Proceedings
of 16th International Conference Software
Engineering, 1994

虔誠(chéng)的寫(xiě)文檔

  • 為類描滔、接口、方法踪古、參數(shù)含长、異常、構(gòu)造器編寫(xiě)文檔
    • 類:實(shí)例代表什么
    • 方法:方法與使用者之間的約定伏穆,如先決條件拘泞、后決條件、副作用
    • 參數(shù):表示單位枕扫、表單陪腌、所有權(quán)

api設(shè)計(jì)決策要考慮性能影響

  • 不好的決策可能會(huì)限制性能,如:
    • 類型可變(參考下一條的例子)
    • 使用構(gòu)造方法替換工廠
    • 使用實(shí)現(xiàn)類型代替接口
  • 不要試圖通過(guò)包裝api來(lái)提升性能
    • 好的設(shè)計(jì)通常伴隨好的性能

api設(shè)計(jì)決策對(duì)性能的影響是真實(shí)并且持久的

  • Component.getSize() 返回 Dimension
  • Dimension是可變的
  • 每次調(diào)用getSize()將會(huì)分配一個(gè)Dimension
  • 導(dǎo)致數(shù)百萬(wàn)不必要的對(duì)象
  • 即使在1.2版本中增加新方案烟瞧,老的代碼依舊執(zhí)行很慢

api必須與平臺(tái)和平共存

  • 按規(guī)律辦事
    • 遵守標(biāo)準(zhǔn)的命名約定
    • 避免廢棄的參數(shù)類型和返回類型
  • 利用好api的特性
    • 泛型诗鸭、枚舉、默認(rèn)參數(shù)参滴、varargs
  • 了解并避免api的陷阱
    • Finalizers, public static final arrays

類設(shè)計(jì)

減少可變性

  • 類應(yīng)該是不可變的强岸,除非有更好的理由
    • 優(yōu)點(diǎn):簡(jiǎn)單、線程安全砾赔、可重用
    • 缺點(diǎn):每個(gè)值都有單獨(dú)的對(duì)象
  • 如果是可變的蝌箍,保持狀態(tài)空間盡可能小和良好的定義
    • 明確何時(shí)調(diào)用那個(gè)方法是合法的

Bad: Date, Calendar
Good: TimerTask

子類只出現(xiàn)在有意義的地方

  • 子類化意味著可替代性
    • 僅當(dāng)is_a關(guān)系才出現(xiàn)子類
    • 否則,請(qǐng)使用組合
  • 公共類不應(yīng)該僅僅為了容易實(shí)現(xiàn)而子類化其他公共類

Bad: Properties extends Hashtable暴心, Stack extends Vector
Good: Set extends Collection

設(shè)計(jì)和文檔用于繼承妓盲,否則就禁止它

  • 繼承違反了封裝原則,子類對(duì)超類的實(shí)現(xiàn)細(xì)節(jié)敏感
  • 如果你允許子類化专普,文檔留作自用
  • 保守策略:所有的具體類都final化

Bad: Many concrete classes in J2SE libraries
Good: AbstractSet, AbstractMap

方法設(shè)計(jì)

不要讓使用者做任何模塊可以做的事情

  • 減少對(duì)樣板代碼的需求
    • 通常通過(guò)剪切和粘貼來(lái)完成
    • 丑陋悯衬,煩人,容易出錯(cuò)
image.png
image.png

不要違反最小化原則

  • api的用戶不應(yīng)該對(duì)api的行為感到驚訝
  • 這值得付出很大的努力檀夹,甚至犧牲一些性能
public class Thread implements Runnable {
    // Tests whether current thread has been interrupted.
    // Clears the interrupted status of current thread.
    public static boolean interrupted();
    }
}

快速失敗-當(dāng)發(fā)生錯(cuò)誤時(shí)筋粗,盡可能早的報(bào)錯(cuò)

  • 編譯時(shí)最好- 靜態(tài)類型、泛型
  • 運(yùn)行時(shí)击胜,首先調(diào)用發(fā)生錯(cuò)誤的方法
    • 方法應(yīng)該是原子失敗的

使用適當(dāng)?shù)膮?shù)和返回類型

  • 在輸入時(shí)亏狰,優(yōu)先選擇接口類型而不是類
    • _提供靈活性、性能
  • 使用最具體的輸入?yún)?shù)類型
    • 將錯(cuò)誤從運(yùn)行時(shí)移動(dòng)到編譯時(shí)
  • 如果存在更好的類型偶摔,不要使用string
    • 字符串是笨重的暇唾,容易出錯(cuò)的,而且很慢
  • 不要使用浮點(diǎn)數(shù)來(lái)表示貨幣值
    • 二進(jìn)制浮點(diǎn)導(dǎo)致不精確的結(jié)果!
  • 使用double(64位)而不是float(32位)
    • 精度損失是真實(shí)的,性能損失可以忽略不計(jì)

使用一致的參數(shù)排序

  • 尤其重要的是策州,如果參數(shù)類型相同
  • 如Collections中的方法瘸味,第一個(gè)參數(shù)一般都是被修改或被查詢的。
image.png
image.png

image.png
image.png

避免長(zhǎng)的參數(shù)列表

  • 三個(gè)或更少的參數(shù)是理想的
    • 更多的用戶將不得不參考文檔
  • 一長(zhǎng)串類型相同的參數(shù)是有害的
    • _程序員誤轉(zhuǎn)了參數(shù)
    • 程序仍在編譯够挂、運(yùn)行旁仿,但行為不正常!
  • 兩種縮短參數(shù)列表的技術(shù)
    • 拆分方法
    • 創(chuàng)建助手類來(lái)保存參數(shù)

避免需要異常處理的返回值

  • 返回零長(zhǎng)度數(shù)組或空集合,而不是null

Bad:


image.png
image.png

異常設(shè)計(jì)

支持unchecked異常

?checked-客戶必須采取恢復(fù)措施
?unchecked–編程錯(cuò)誤
?過(guò)度使用checked的異常會(huì)導(dǎo)致樣板


image.png
image.png

在異常中包含失敗捕獲信息

  • 允許診斷和修復(fù)或恢復(fù)
  • 對(duì)于未檢查的異常孽糖,消息就足夠了
  • 對(duì)于已檢查的異常枯冈,提供訪問(wèn)器
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市办悟,隨后出現(xiàn)的幾起案子尘奏,更是在濱河造成了極大的恐慌,老刑警劉巖病蛉,帶你破解...
    沈念sama閱讀 206,013評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件炫加,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡铺然,警方通過(guò)查閱死者的電腦和手機(jī)俗孝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)魄健,“玉大人赋铝,你說(shuō)我怎么就攤上這事【骷瑁” “怎么了柬甥?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,370評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)其垄。 經(jīng)常有香客問(wèn)我,道長(zhǎng)卤橄,這世上最難降的妖魔是什么绿满? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,168評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮窟扑,結(jié)果婚禮上喇颁,老公的妹妹穿的比我還像新娘。我一直安慰自己嚎货,他們只是感情好橘霎,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著殖属,像睡著了一般姐叁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 48,954評(píng)論 1 283
  • 那天外潜,我揣著相機(jī)與錄音原环,去河邊找鬼。 笑死处窥,一個(gè)胖子當(dāng)著我的面吹牛嘱吗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播滔驾,決...
    沈念sama閱讀 38,271評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼谒麦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了哆致?” 一聲冷哼從身側(cè)響起绕德,我...
    開(kāi)封第一講書(shū)人閱讀 36,916評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎沽瞭,沒(méi)想到半個(gè)月后迁匠,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,382評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡驹溃,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評(píng)論 2 323
  • 正文 我和宋清朗相戀三年城丧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片豌鹤。...
    茶點(diǎn)故事閱讀 37,989評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡亡哄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出布疙,到底是詐尸還是另有隱情蚊惯,我是刑警寧澤,帶...
    沈念sama閱讀 33,624評(píng)論 4 322
  • 正文 年R本政府宣布灵临,位于F島的核電站截型,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏儒溉。R本人自食惡果不足惜宦焦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望顿涣。 院中可真熱鬧波闹,春花似錦、人聲如沸涛碑。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,199評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蒲障。三九已至歹篓,卻和暖如春瘫证,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背滋捶。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,418評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工痛悯, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人重窟。 一個(gè)月前我還...
    沈念sama閱讀 45,401評(píng)論 2 352
  • 正文 我出身青樓载萌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親巡扇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子扭仁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容