大道至簡--API設計的美學

1.前言

對於前端開發而言,肯定會和API打交道,大家也都會想過怎麼設計自己的API。優秀的 API 之於代碼,就如良好內涵對於每個人。好的 API 不但利於使用者理解,開發時也會事半功倍,後期維護更是順風順水。至於怎麼設計API,今天就提下我自己的一些建議。如果大家有什麼好的想法,歡迎指點。

2.命名

良好的一個命名習慣,就是效率開發的第一步。如果命名規範,對自己而言,文件整理有很大的幫助,後期修改文件、可以快速的定位文件,命名規範,也顯得自己專業。對團隊而言,如果有統一的規範命名,交接時可以減少大量的學習和溝通成本。

關於命名,下面提點幾個小建議

2-1.正確拼寫

這個應該說是命名的一個底線了,經常性出現,單詞拼寫錯誤,搞得自己或者團隊的人都一頭霧水的情況不再少數。我遇到情況比較深刻的有

中文大意期望實際表單formfrom報名sign-upsign-in採納adoptadept內容contentcontend測試testtext聯繫contactcontract高度heightheigth寬度widthwidht移動mobilemoblie標籤tabtap

這些單詞,如果是拼寫錯誤還好,至少編輯器都會提醒。但是如果寫錯了,但是單詞又是正確的單詞就可大可小了(表單,報名,採納,內容這些例子,單詞寫錯了,意思變了,但是單詞是正確的,編輯器都不會提醒)。

試過挖坑比較深的一次就是:一個活動,有報名,有簽到的功能!處理方法如下

獲取已報名用戶信息:getSignUpUserList,

重置報名的數據:resetSignUpUser,

提交報名操作:signInDo

獲取已簽到用戶信息:getSignInUserList,

重置簽到的表單數據:resetSignInUser,

提交簽到的操作:signUpDo

修改bug的時候,完全懵逼了,原因大家懂的。

2-2.注意單複數

所有涉及遍歷,操作對象,數組,集合的函數,建議都採用複數。

對於展現複數,不同公司有不同的習慣,但是得統一,比如產品列表-productList。這裡用了list表示複數,再其它地方,就不建議使用products這種方式表示複數了

2-3.用詞準確

這個主要的兩方面的內容

2-3-1.單詞意思搞錯

比如彈窗上面的信息,有些時候見到,使用包含notice的字樣,但是實際上,notice的中文意思,準確的應該是‘公告,告示,聲明’之類。

一個彈窗這樣的會話消息,建議使用message這個字樣。notice應該像‘公告,告示,聲明’之類的情況使用。

2-3-2.正反詞義單詞錯用

比如關閉彈窗的方法,的方法是closeDialog,然後顯示彈窗用的又是showDialog。show的意思是‘顯示’,反義詞應該是hide‘隱藏’。而close意思是關閉,反義詞應該是open。

附常用反義詞組(有些帶縮寫)

inoutonoffprevnextshowhidecloseopensuccessfailbeforeafterbeginend

2-4.命名意義

這一塊,本來打算放在2-2裡面講的,因為命名如果有意義也是一個底線。但是最後放在這裡,是因為這個情況在函數里面出現得不多,更多應該出現在普通變量裡面(相信很多人會遇到過這樣的命名:var n1,n2,n3;)。關於命名,還是建議大家要起有意義名稱,不使用沒意義的命名。

遇到最多的情況,就是圖標的命名方面。

比如下面的圖標(選自某平臺的底部導航欄),點擊不同的圖標出發不同的方法。

大道至簡--API設計的美學

很多人喜歡下面的命名

//版本1function handle1(){
}function handle2(){
}//版本2function handleA(){
}function handleB(){
}//版本3function handleOne(){
}function handleTwo(){
}

這樣的命名,別人函數了,就算是元素的 class 。這樣的命名在後期維護絕對增加了難度。甚至可能導致重構。

建議的姿勢

function handleHome(){
}function handleCollect(){
}

2-5.命名格式

文章說的API,主要針對的是函數,但是在這一小塊裡面,也列舉一下其它的目標的建議命名方式。

待命名對象推薦名稱圖片‘-’ ‘_’ 分割class,id‘-’ 分割文件,變量駝峰命名臨時變量‘_’ 開頭,駝峰命名

2-6.處理中文拼音

對於中文拼音,應該說只有一種情況,被中國人創造出來,沒有英文翻譯的。

命名含義taobao淘寶weibo微博zongzi粽子pinyin拼音

在一年多以前,遇到一箇中二的命名-dengluDo。當時一直不知道是什麼玩意,後來向那個人打聽才知道,是執行登錄的操作,denglu是中文拼音,do又是英文,這樣的命名。後期如果維護,他不哭,算我輸。

2-7.命名潛規則

有些情況,給特定的對象命名,還要用特定的名字,可以說是潛規則吧。印象最清楚的就是給按鈕命名要麼全拼,要麼寫btn。很清楚的記得我一個老師說過:寫but,bto的程序也能正常運行,也沒人說你錯,但是我做面試官,就是不錄用你,就說你不專業。

待命名對象推薦名稱錯誤示範按鈕btnbut bto背景bgback background模板tpltem提示信息msgmes標籤欄tabtit網站大圖(廣告宣傳圖)bannerban註冊registersign-in

3.參數

對於函數而言,參數是用戶設置最頻繁,也是最關心的部分,合理設計函數參數,這一步很重要,直接影響函數的使用。

3-1.const入參

這個應該說是一個習慣吧,不要直接改變入參的值。這個規則的初衷是解決函數副作用問題。如果參數是一個引用類型的數據,如果在函數內修改了參數,到時候將會使得原本的數據發生改變,往往會發生難以追蹤的問題。

3-2.控制參數數量

參數的數量,個人建議就是,超過3個,使用對象進行封裝。因為如果API參數越多,那麼使用對於這個API的記憶成本就越大,易用性也很受影響。

比如下面的例子:

encryptStr: function (str, regArr, type, replacement) { var regtext = '',
Reg = null,
_type=type||0,
replaceText = replacement || '*'; //ecDo.encryptStr('18819322663',[3,5,3],0)
//result:188*****663
//repeatStr是在上面定義過的(字符串循環複製),大家注意哦
if (regArr.length === 3 && type === 0) {
regtext = '(\\w{' + regArr[0] + '})\\w{' + regArr[1] + '}(\\w{' + regArr[2] + '})'
Reg = new RegExp(regtext); var replaceCount = this.repeatStr(replaceText, regArr[1]); return str.replace(Reg, '$1' + replaceCount + '$2')
} //ecDo.encryptStr('asdasdasdaa',[3,5,3],1)
//result:***asdas***
else if (regArr.length === 3 && type === 1) {
regtext = '\\w{' + regArr[0] + '}(\\w{' + regArr[1] + '})\\w{' + regArr[2] + '}'
Reg = new RegExp(regtext); var replaceCount1 = this.repeatStr(replaceText, regArr[0]); var replaceCount2 = this.repeatStr(replaceText, regArr[2]); return str.replace(Reg, replaceCount1 + '$1' + replaceCount2)
} //ecDo.encryptStr('1asd88465asdwqe3',[5],0)
//result:*****8465asdwqe3
else if (regArr.length === 1 && type === 0) {
regtext = '(^\\w{' + regArr[0] + '})'
Reg = new RegExp(regtext); var replaceCount = this.repeatStr(replaceText, regArr[0]); return str.replace(Reg, replaceCount)
} //ecDo.encryptStr('1asd88465asdwqe3',[5],1,'+')
//result:"1asd88465as+++++"
else if (regArr.length === 1 && type === 1) {
regtext = '(\\w{' + regArr[0] + '}$)'
Reg = new RegExp(regtext); var replaceCount = this.repeatStr(replaceText, regArr[0]); return str.replace(Reg, replaceCount)
}
}

大家可以看上面的註釋,就知道這段代碼的具體作用了,如果想想就找個參數,我必須要除了記得4個參數的作用,還要記得參數的順序。

如果使用對象記錄參數,用戶只需要記得4個參數的作用,不需要記參數的順序。

encryptStr: function (obj) { var _default={ type:0,
replacement:'*'
}; for(var key in obj){
_default[key]=obj[key];
}
},//調用方式ecDo.encryptStr({str:'18819266335',regArr:[5],type:0,replacement:'-'});

這樣還有一個好處就是,比如像剛才的函數,type這個參數,我想保留默認值,偷懶不傳。原來的方案,就得這樣傳。

ecDo.encryptStr('1asd88465asdwqe3',[5],'','+');

這樣肯定是會激起不少有代碼潔癖的開發者,比如我。如果使用對象,就很好避免了。

ecDo.encryptStr({str:'18819266335',regArr:[5],replacement:'-'});

3-3.前置相關性高的參數

這個應該沒什麼可能,就一個意思:必填重要的參數前置,可省略的參數後置。

比如下面的例子

/格式化處理字符串//ecDo.formatText('1234asda567asd890')//result:"12,34a,sda,567,asd,890"//ecDo.formatText('1234asda567asd890',4,' ')//result:"1 234a sda5 67as d890"//ecDo.formatText('1234asda567asd890',4,'-')//result:"1-234a-sda5-67as-d890"formatText: function (str, size, delimiter) { var _size = size || 3, _delimiter = delimiter || ','; var regText = '\\B(?=(\\w{' + _size + '})+(?!\\w))'; var reg = new RegExp(regText, 'g'); return str.replace(reg, _delimiter);
},

調用大家都看得出來。如果API這樣設計

鏈接:https://www.imooc.com/article/44524


分享到:


相關文章: