出色的 JavaScript API 設計秘訣

来源:http://www.cnblogs.com/shouce/archive/2016/04/15/5395210.html
-Advertisement-
Play Games

設計是一個很普遍的概念,一般是可以理解為為即將做的某件事先形成一個計劃或框架。 (牛津英語詞典)中,設計是一種將藝術,體系,硬體或者更多的東西編織到一塊的主線。軟體設計,特別是作為軟體設計的次類的API設計,也是一樣的。但是API設計常常很少關註軟體發展,因為為其他程式員寫代碼的重要性要次於應用UI ...


設計是一個很普遍的概念,一般是可以理解為為即將做的某件事先形成一個計劃或框架。 (牛津英語詞典)中,設計是一種將藝術,體系,硬體或者更多的東西編織到一塊的主線。軟體設計,特別是作為軟體設計的次類的API設計,也是一樣的。但是API設計常常很少關註軟體發展,因為為其他程式員寫代碼的重要性要次於應用UI設計和最終用戶體驗。

但是API設計,作為我們自己寫的庫中提供的公共介面,能夠向調用我們代碼的開發者表現出我們庫的一些特點和功能,所以API設計和UI設計一樣重要。事實上,兩者都是為應用可以提供更好的用戶體驗具有基本的方式。應用UI在用戶UX中占有很重要的位置,應用API是開發者的UX。因此,應用API設計應該被給予和我們提供給用戶的介面相同水平的考慮和關註。正像我們關註UI的功效,簡潔性和優美,我們也應該同樣的評估API的功效,簡潔性和代碼的優美性!

API設計——javascript API設計的內容,呈現了唯一的挑戰對所有的開發者,不管是否你正在開發一個公共的庫或者一個內部的庫。javascript的動態性,庫使用者的匿名和需求的模棱兩可都給API設計者呈現了一個令人畏懼的挑戰。然而對於一個好的API設計是沒有捷徑的,但是可以從現代流行的一些javascript庫中提取出一些設計準則是可能的!

API設計: 天使和惡魔的鬥爭

javascript API中差的設計會給使用你API的開發者和你帶來高的花費。差的設計會導致浪費,使用你API的開發者會因為設法搞弄明白你介面而浪費時間,而API的開發者會因為處理不斷增加的需求和解決使用者的困惑而浪費時間。然而幾乎所有的API當初被開發的時候,都是為了能夠提取相同的功能,方便調用並節約時間。但設計不好的API會使你的庫使用者和你產生疑惑,這些庫真的能節約時間嗎?

優秀的API設計,一方面,完成了提取的目標,同時也實現了自我描述。當一個API被良好的設計,使用者可以快速地和直觀地完成工作,完全不用不停的使用文檔或者持續的訪問支持或者解答網站。你也可以通過封裝一些開發者需要自己花大量時間開發的一些特征來節約庫開發者的時間。好的設計不僅節約開發者的時間,可以使他們看起來更加聰明和有責任。同樣幫助你的用戶看起來聰明和能幹也會使你看起來更加的牛逼!

對於javascript來說,API設計特別重要

不管什麼編程語言或者框架,API設計是重要的,API設計的重要性對於javascript來說是高於其它許多語言的。首先,作為一個動態的和後期綁定的語言,javascript沒有編譯器可以實現一個安全網或者檢測單元功能,所以javascript不可以發現你代碼中的錯誤。Linting 或檢驗框架 如 JSLint 和JSHint 可以幫助我們。這些框架的功能可以指出javascript中的一些普遍的錯誤,但是當我們使用API時,他們卻不能發現javascript的錯誤。

這一切都取決於你,你可以開發一個具有良好設計的API,這個API可以幫助你的用戶掉進眾所周知的“成功坑”,這就意味著你的庫對於開發者來說是舒服的和熟悉的,同時也提供了積極的強化和當開發者和你的代碼交互時建立的信心。

“掉進成功的坑裡”最好的例子是jQuery 通過CSS選擇器語法獲取DOM元素的運用。例如,如果我想要獲取所有帶有類名的article元素,我可以運用jQuery這樣做:

1 $("article.blogPost").fadeIn();

選擇器article.blogPost和下麵展現使用完全一樣的語法,這絕不是偶然的!

1 2 3 4 5 article.blogPost { border-radius: 10px;   box-shadow: 0px 0px 10px 2px #ccc; }

jQuery的選擇器引擎被設計為了使我和其他開發者能夠使我對CSS選擇器的理解和它的引擎進行交互。結果可想而知,如果jQuery需要我用一種新的,為特定目的形成的語法,我將失去快速,明顯和高效。

我們可以獲得靈感從這些框架中,如jQuery,或者其他框架,並應用這些靈感到我們的設計中。然而,獲得靈感並不是抄襲,有個度的問題,任何設計過API的人如果是僅僅的基於別人的想法,不管好與壞,他都將繼承。如果我們將在好的javascript中獲得的準則運用到其他領域中,我們能開發擁有好的API的框架,這些API設計能被運用在任何情況下。

出色的Javascript APIs設計秘訣

雖然軟體不具有與繪畫或建築類似的視覺評價標準,我們仍傾向於使用與物理實體一樣的形容詞來描述軟體質量。例如,使用“優雅的”與“漂亮的”來贊美軟體並不罕見。如果用與物理實體相似的形容詞描述軟體介面是合理的話,那麼當然也可以使用與之相同的原則來評價軟體設計。

在本節,將四個來自藝術領域的流行設計原則擴展至API設計中:

  • 和諧一致
  • 平衡
  • 對稱
  • 重點突出

對每一個原則,將列出一到多個實例來說明,這些例子表明流行的Javascript庫API設計是怎樣遵循這些原則的。

原則1:一致性&協調性

在藝術作品中,一致性是一個作品背後不可缺少的觀念,或者說設計者如何把一些事物組成連貫的一個整體。協調性,從另一方面來說,是一個作品相似元素的佈局,這會在考慮整體時產生一種簡潔的感覺。

對於API的設計者,這些原則可以通過在類庫使用類似的和(或者)統一的元素來實現。就拿Kendo UI來說吧,一個創建富web應用程式的javascript框架。Kendo UI提供了一系列的UI控制項和工具,這些都可以通過一個簡單的語法初始化。比如,如果我想從一個無序列表創建一個樹形控制項(TreeView),我只需調用以下方法:

1 $("ul.tree").kendoTreeView({ /* Configuration goes here */ });

出色的 JavaScript API 設計秘訣

Kendo UI樹形組件

如果我想通過一個列表創建一個面板PanelBar,我只需稍微改成不同的調用方法.

1 $("ul.panel").kendoPanelBar({ /* Configuration goes here */ });

出色的 JavaScript API 設計秘訣

Kendo UI 面板組件

Kendo UI 對所有組件使用一致的kendoX語法,促進整體的協調。更重要的,這樣的設計依賴jQuery對象為DOM元素封裝了統一的一層,使設計有利於所有熟悉jQuery開發者。數百萬開發者使用類似的“土語”(jQuery語法),Kendo UI可以順利地跨庫使用。

另一個協調的案例是Backbone的[object].extend語法創建對象,繼承和擴展Backbone的Models,Views,CollectionsRouters的功能。用如下代碼就可以創建一個Backbone Model,帶有Backbone的完整支持,也可以自定義我需要的功能:

1 2 3 4 5 var Book = Backbone.Model.extend({   initialize: function() { ... },   author: function() { ... },   pubDate: function() { ... }, });

統一和協調的目的是讓API新手感覺熟悉和舒服。通過雖然功能不同,但是語法相同或相似,使API變得熟悉,大大減輕了開發者使用新工具的負擔。

原則 2 :平衡

下一條原則是平衡,組織元素時不會讓某個部分過於重量級而蓋過其它部分,使用時不穩定。藝術作品里,平衡就是視覺權重。即使不對稱,作品中仍能感覺到不對稱下的平衡,因為它遵循某種模式。上下文中的API設計的平衡,我特指代碼的視覺權重和可預測性(看得出功能)。 平衡的API讓人覺得其組成部分屬於彼此,他們行為相同,或互補地完成一個目標。通過擴展,APIs也可以感覺平衡,它們允許開發人員簡單的預測其他API並使用。如Modernizr屬性測試,它們的平衡性在兩個方面,a)屬性名對應HTML5和CSS術語和API名稱,b)每個屬性測試統一地返回true或false值。

1 2 3 4 5 6 7 8 // All of these properties will be 'true' or 'false' for a given browser   Modernizr.geolocation   Modernizr.localstorage   Modernizr.webworkers   Modernizr.canvas   Modernizr.borderradius   Modernizr.boxshadow   Modernizr.flexbox

出色的 JavaScript API 設計秘訣

訪問一個單一的屬性來告訴開發者需要瞭解到的相關屬性,以便通過它訪問每一個其他屬性,一個高質量API的強大之處就在於它的簡單。平衡性也保證了我寫和Modernizr交互的代碼在每次讀寫時具有相同的視覺加權。如何在我使用和訪問API時看起來和感覺上一樣,而不顧我的慣例。另一方面,如果Modernizr添加了一個polyfill Canvas的API,不僅僅是類庫的視覺加權受到新API的影響,Modernizr的範圍和用途也將大大擴大,並且我在和API交互時可預測性也受到了限制。

達到平衡的另一種方式是通過依靠開發人員對概念的熟悉獲得可預測性的結果。一個典型的例子就是jQuery’s selector syntax(jquery選擇器的語法),它映射css1-3的選擇器到自己的DOM選擇器引擎:

1 2 3 $("#grid") // Selects by ID $("ul.nav > li") // All LIs for the UL with class "nav" $("ul li:nth-child(2)") // Second item in each list

通過使用一個熟悉的概念並且映射到自己的類庫,jquery避免了新的選擇器語法,同事也創建了一個機制讓新用戶通過一個可預測的API快速的把類庫應用到生產。

原則 3: 相稱性

接下來的原則是相稱性,它是用來衡量一個作品中元素的大小和數量的。與其說一個好的API是一個小的api,相稱性是相對於用途的大小。一個相稱的API它的API錶面和它的能力範圍相匹配。

例如,Moment.js,一個流行的日期轉換和格式化類庫,可以把它視為具有相稱性,因為它的API表層是緊湊的,它和類庫的目的明確的匹配。Moment.js用於處理日期,它的API提供了便利的功能用來處理javascript Date對象:

1 2 moment().format('dddd'); moment().startOf('hour').fromNow();

出色的 JavaScript API 設計秘訣

對於一個有針對性的類庫,像Moment.js,保持API的專註和簡單是非常重要的。對於更大和更廣闊的類庫,API的大小應當能夠反映出類庫自身的能力。

Underscore來說,作為一個多種用途功效的庫,它提供大量便利的函數,這些被設計的函數是用來幫助開發者處理javascript集合,數組,函數和對象。它的API量遠遠超過像Moment.js這樣的庫,但是Underscore也是成比例的,因為庫中每個函數都有自己的功效目的。考慮下麵的例子,前兩個例子用Underscore來處理數組,最後一個來處理字元串。

1 2 3 4 5 6 7 8 9 _.each(["Todd", "Burke", "Derick"], function(name){   alert(name); });   _.map([1, 2, 3], function(num){   return num * 3; });   _.isNumber("ten"); // False

出色的 JavaScript API 設計秘訣

當一個庫逐漸成長的過程中,維持比例的挑戰變的更加具有嚴峻。為了確保添加進庫的每個功能和函數都能加強庫的目的,需要更多的考慮投入。對於一個大的庫像kendo UI,易擴展性的目的並不是意味著我們需要往庫中添加每個特性。對於一個像kendo一樣大的庫,功能對象和特性應該證明它們的價值才能被庫包含。例如, Kendo UI’s JavaScript 基於DataSource, 它能夠被用來查詢和處理遠程數據。

1 2 3 4 5 6 7 8 9 10 var dataSource = new kendo.data.DataSource({   transport: {     read: {       url: "http://search.twitter.com/search.json",         dataType: "jsonp",         data: { q: "API Design" }       }     },   schema: { data: "results" } });

初看第一眼,它好像一個習以為常的數據源,感覺超出了庫本身的基本目的。然而今天網站的裝飾都需要動態數據的支持。數據源的引入允許Kendo UI可以使用一個穩定,並舒適的範式在整個庫範圍內來解決遠程數據。

讓一個API轉變為一個名符其實的javascript垃圾抽屜,對於一個庫的擴展這是危險的,但對於庫來說,這也不是唯一的危險。掉入一個不讓你的API伴隨著庫的成長圈套,或者由於某些人為原因,限制你庫的大小,這些同樣都是危險的!

不處理API增長最好的一個例子是jQuery的 jQuery or $ function。和我一樣有成千上萬的開發者喜歡jQurey, 但它的門戶方法是有點亂的,從DOM選擇到在jQuery對象中包含DOM元素,這個方法提供了超過11個獨立超負荷選擇方式。

就大部分而言,有些不是十分相關的特性被硬塞進同一個API。從全局看,jQuery是一個大的庫並且能被認為庫比例是合理的。另一方面,當我們嘗試將一個功能硬塞進一個單一介面並且不考慮庫比例,jQuery方法也可以實現這樣的功能。

如果你發現你正在將一個不相干的特性強塞進已經存在的方法,或者正在想法設法使一個並不適合API的函數的添加合理化,你需要做的改變是鬆開皮帶並且讓庫呼吸。你的用戶在調用一個新的可以自我描述名字的函數時,將會更加節省時間,並且不會給另一個已經存在的方法添加負擔。

原則 4: 強調性

在藝術作品中,強調是利用對比來使作品中某一方面脫穎而出形成一個焦點。在許多API中,焦點可能是一個通道或者類庫主要方法的錨點。另外一個關於強調性的例子可以參考“鏈接”方式或者fluent API,它通過增加強調性效果突出了類庫中心對象。jquery傾向於從許多功能演示中的強調這個對象:

1 2 3 4 5 $('ul.first').find('.overdue')   .css('background-color','red')   .end()   .find('.due-soon')   .css('background-color', 'yellow');

對於許多現代的類庫,另一個關於強調的例子是可擴展性:類庫創建者沒有提供的那部分,會為你提供一個工具你可以自己完成相關擴展。

一個典型的例子可以參考 jQuery’sfn(pronounced “effin”) namespace, 一般的擴展點可以通過數不清的插件和補充的類庫來完成:

1 2 3 4 5 6 7 8 9 10 (function($) {   $.fn.kittehfy = function() {     return this.each(function(idx, el) {              var width = el.width,         height = el.height;       var src= "http://placekitten.com/";       el.src= src + width + "/" + height;     });   }; })(jQuery);

另一個擴展性的例子是Backbone的“extend”的函數,我們已經在本文中看到過:

1 2 3 4 5 6 7 8 9 var DocumentRow = Backbone.View.extend({   tagName: "li",   className: "row",   events: {     "click .icon": "open",     "click .button.edit": "openEditDialog"   },   render: function() { ... } });

出色的 JavaScript API 設計秘訣

可擴展作為強調性的一方面是因為它讓我們意識到這樣的一個事實,已有的類庫並不意味著一切是完美的,同時也鼓勵我們擴展適合自己的類庫。當類庫支持擴展時,它們不僅開啟了新的用途,也使無數開發者受益於一般的用途。一個最好的例子是Backbone.Marionette框架,一個擴展於Backbone的類庫,它的目標是“簡化大型的javascript應用程式的結構”。如果不是像Backbone那樣的類庫擴展,Marionette之類的類庫將變得非常複雜,甚至不可能實現。

API 設計:不只為庫代碼編寫者

如果你不是一位 JavaScript 庫的編寫者,而是一位 JavaScript 應用開發者或庫的實現者,你可能會認為本文中的原則並不適用於你。畢竟,我們大多數人在聽到“API”的時候,往往想到的是第三方庫,一如我在本文中的示例一樣

事實是,API ,如同其定義所言,無非就是一個提供給他人利用的隔離功能的介面。 現在,讓我用一句老話來強調很重要的一點:編寫模塊化的 JS 代碼是為了實用,使用的次數並不重要。

正如本文中引用的類庫,你可以把自己的javascript代碼公開介面給其他人。即使你的代碼的用戶是一小部分或內部團隊——甚至你構建自己的一個私有類庫——你不必像一個公開類庫的作者那樣考慮本文中API設計原則和這些原則的實現。利用API設計的好處是即使只針對一個使用者,也要像對數百萬使用者一樣設計。

因為API的設計代表著對開發者的用戶體驗,它就像UI設計對於最終用戶的重要性一樣。正如我們可以通過學習一些原則和參考一些好的或者壞的例子來開發出優秀的UI一樣,我們也可以通過同樣的方式學習到更好的API設計。應用文中提到的四個原則,以及其他你自己發現的原則,可以幫助你建立出優秀的API,並且讓用戶得到良好的體驗。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 背景圖片自適應 元素自適應居中於網頁 CSS3使圖片變灰 ...
  • 今天看到一篇有關 css3事件的博文,一時興起便整理下相關的資料。 點擊按鈕,可以實現開關的滑動效果。 今天看到一篇有關 css3事件的博文,一時興起便整理下相關的資料。 點擊按鈕,可以實現開關的滑動效果。 今天看到一篇有關 css3事件的博文,一時興起便整理下相關的資料。 點擊按鈕,可以實現開關的 ...
  • css3被拆分成如下的小模塊,選擇器,盒模型,背景和邊框,文字特效,2D/3D轉換,動畫,多列佈局和用戶界面 2D轉換 使用transform:屬性來為元素設置2D轉換,相容瀏覽器加首碼 –webkit- -moz- 使用rotate()方法,讓元素旋轉一定的角度,參數:角度 例如:transfor ...
  • 今天看到一篇有關input事件的博文,一時興起便整理下相關的資料。 事件: onchange:onchange事件是在前後內容改變,並且失去焦點之後才會觸發。 oninput:oninput事件則會在value改變時就觸發。 還有一個onpropertychange事件,效果與oninput相似,但 ...
  • 本文內容 項目結構 AngularJS datepicker AngularJS+jQueryUI datetimepicker Github Demo 項目結構 圖 1 項目結構 AngularJS datepicker 圖 2 Angular-ui-bootstrap datepicker in ...
  • 網上找了份jquery的操作節點方法清單。如下: 方法 源包裝集/字串 目標包裝集體 特性描述 A.append(B) B A 若目標包裝集只匹配一個元素,則源(也包括同源包裝集匹配的所有元素)將被移動到目標位置;若目標包裝集包含多個元素,則源將保留在原來的位置,但同時複製一份相同的副本到目標位置。 ...
  • 如何讓一個div居於頁面中間,我今天說的是讓一個div水平居中同時垂直居中,而不是簡單的top:50%,left:50%。當然,我們就按一開始的思路寫一下:top,left屬性都設為50%,看一下效果。 從我的截圖可以看出,div的左頂點剛好在頁面的中心點處。現在的思路是,如何移動div然後讓div ...
  • 編輯器載入中...49個jquery代碼經典片段,這些代碼能夠給你的javascript項目提供幫助。其中的一些代碼段是從jQuery1.4.2才開始支持的做法,另一些則是真正有用的函數或方法,他們能夠幫助你又快又好地把事情完成。如果你發現你任何可以做得更好的地方的話,歡迎把你的版本粘貼在評論中! ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...