【投稿】聽阿里云工程師談談如何開發(fā)一個優(yōu)秀的 SDK
作者簡介:德勝 現(xiàn)任阿里視頻云團隊資深開發(fā)工程師,多年移動端音視頻經驗,現(xiàn)在從事業(yè)務架構設計、客戶技術支持等相關工作。
越來越多的開發(fā)者選擇使用 SDK 來輔助開發(fā),作為一種工具,它可以幫助你快速建立應用軟件,而省去了編寫硬件代碼和基礎代碼架構的過程。我們團隊一直致力于移動視頻領域 SDK 的開發(fā),踩過坑趟過河,遇到了很多問題也總結了一些經驗,下面是我們總結的一個好的SDK應該具備的特質:
易用性,穩(wěn)定性,輕量,靈活,優(yōu)秀的支持
一、易用性
因為工作的關系我接觸了很多的開發(fā)者,其中有行業(yè)知名的公司的開發(fā)者,也有極小的個人開發(fā)者.有一個現(xiàn)象很有意思,不管是能力較強的開發(fā)者還是能力一般的開發(fā)者,他們都會不停的對你的 SDK 吐槽。因為他們對于好用的標準是不一樣的,所以你必須要將你的 SDK 易用性考慮到極致,不然后續(xù)的技術支持將是一個十分痛苦的事情.
1、不要過度設計,過度設計是程序員常常犯的錯誤,如果只是一個演示 demo,應該盡量的簡單,簡單到最基礎的程序員都能夠看懂;
2、接口盡量的見名知義;
3、要相信絕大多數(shù)的開發(fā)者都是不看文檔的,于是根據(jù)開發(fā)者的直覺去設計 API,這樣聽起來是不是太靠譜?事實上比如你的 SDK 的生命周期設計方法跟系統(tǒng)差異性不大,比如你的播放器的接口設計跟系統(tǒng)播放器相差不大,那對開發(fā)者來講就是福音;
4、接口能夠統(tǒng)一的盡量統(tǒng)一,比如 iOS 和 Android 的接口,應該盡量的統(tǒng)一;
5、盡量多的默認參數(shù),這里面有一些小的技巧,以下我提一個小的例子,比如我們的 SDK,我們有一個跳轉錄制的接口,事實上就是將一堆的參數(shù)給到下一個 SDK 頁面,讓 SDK 接收參數(shù),我們選擇給一個結構體暴露給用戶,如下:
AliyunVideoParam recordParam = new AliyunVideoParam.Builder()
.setResulutionMode(resolutionMode) //設置錄制分辨率,目前支持360p,480p,540p,720p
.setRatioMode(ratioMode) //設置視頻比例,目前支持1:1,3:4,9:16
.setRecordMode(RecorderDemo.RECORD_MODE_AUTO) //設置錄制模式,目前支持按錄,點錄和混合模式
.setFilterList(eff_dirs) //設置濾鏡地址列表
.setBeautyLevel(80) //設置美顏度
.setBeautyStatus(true) //設置美顏開關
.setCameraType(CameraType.FRONT) //設置前后置攝像頭
.setFlashType(FlashType.ON) // 設置閃光燈模式
.setNeedClip(true) //設置是否需要支持片段錄制
.setMaxDuration(max) //設置最大錄制時長
.setMinDuration(min) //設置最小錄制時長
.setVideQuality(videoQuality) //設置視頻質量
.setGop(gop) //設置關鍵幀間隔
.build();
AliyunVideoRecorder.startRecordForResult(this,REQUEST_RECORD,recordParam);這樣有什么好處呢,我們事實上可以預制 N 個參數(shù)。這樣用戶調用一個錄制功能只需要做什么呢?如下:
AliyunVideoParam recordParam = new AliyunVideoParam.Builder().build(); AliyunVideoRecorder.startRecordForResult(this,REQUEST_RECORD,recordParam);
6、上面還說了開發(fā)者對于易用性的標準是不一樣的,面向的需求也是不一樣的,上面的需求只能滿足最基礎的簡單需求,如果要自定義界面,這個時候就需要暴露更加深的接口。于是我們將我們的接口設計分為多層.這樣就基本能夠滿足用戶最初級的要求和自定義屬性的要求。
DEMO--->AliyunVideoRecorder(第一層接口)---->AliyunIRecorder(第二層接口)
二 、穩(wěn)定性
如何保證一個 SDK 的穩(wěn)定性?自動化測試、適配測試、API 的穩(wěn)定、代碼審查、內存檢測、可測試性都缺一不可。
1、自動化測試:依賴系統(tǒng)的自動化測試工具就可以完成人工絕大多數(shù)的自動化UI測試.能夠解放黑盒測試的雙手,這個時候如果有使用 Jenkins 之類的持續(xù)集成的系統(tǒng),你還能夠讓你的開發(fā)者及時的能夠發(fā)現(xiàn)問題、解決問題;
2、適配測試:一個安卓永遠的痛,現(xiàn)在基本沒有很多好的方法,只有去找一些規(guī)律找機器適配,但是做多了就會發(fā)現(xiàn)還是有規(guī)律可循的,比如 GPU 的型號,系統(tǒng)版本,使用的硬件差異,甚至品牌.早期我們也是按 CPU,GPU 型號去買機器的;
3、API 的穩(wěn)定::一個好的 SDK 設計的 API 應該從一開始就需要考慮擴展性,盡量多的考慮將來可能的需求,盡量將這些需求包進來.我見過很多開發(fā)者懊惱如果讓我再設計一次一定能夠將這個接口設計的更好一些 ;
4、代碼審查:一個好的團隊在代碼質量上會下很大的功夫,所以不讓代碼審查淪為形式是一個好 leader 應該考慮的事情.大團隊會做一些交叉 review,開啟 git 的 pull request,寫單元測試等都是不錯的方式
三、輕量
現(xiàn)如今手機 App 的大小直接決定用戶買單不買單( 16G 的 iPhone 哭暈在廁所),在我接觸客戶中發(fā)現(xiàn)越是大公司越在乎對App的大小增加,因為他們的應用已經非常龐大了,像微信,手淘,支付寶這樣的大體量他們都對大小有著極其嚴苛的態(tài)度,產品和技術團隊會直接評估大小增加對用戶的影響。所以你的 SDK 是否輕量直接決定用戶是不是選擇你的 SDK。那如何做到輕量?
1、盡量少的使用第三方庫,如果非要使用這個庫需要考慮這個庫中的源碼是否能夠裁剪,有必要時需要產品一起評估這個功能對大小的增加,有必要時要求產品干掉這個功能;
2、代碼耦合度盡量的低,比如用戶只要一個錄制功能,這個時候就需要評估你的錄制模塊是否獨立,能不能單獨的抽離.你應該盡量的讓你的代碼耦合度低;
- 第三方庫需要暴露實現(xiàn)給用戶.特別是非常常見的庫,比如你一個 json 解析的代碼。你應該定義一些接口,然后實現(xiàn)的類直接暴露給用戶.如果用戶有強烈的替換第三方庫要求,應該讓用戶有權利去替換;
- SDK 不要包含 view 層實現(xiàn)和資源,如果有必要,將 view 層的實現(xiàn)暴露出去。比如:我們在做 SDK 的時候我們始終在考慮怎么樣讓用戶盡量簡單的接入我們的 SDK,盡量少的讓用戶接入的成本低,盡量少的讓用戶少寫代碼.這樣就不可避免需要做一些應用層的事情,于是我們就將 View 層的所有實現(xiàn)都暴露給用戶,然后讓用戶只修改 UI 即可。這樣資源用戶也可以替換,十分方便。
四、靈活
靈活包括幾個點:API 靈活可擴展,API 的可測試性,API 的健壯性性要強。要做到以上任何一點都需要經驗的支持,絕對不要想當然,盡量的從開發(fā)者的角度去設計,會讓自己收獲很多。
1、API 可擴展:在業(yè)務過程中我們總是面對產品不斷的需求壓迫,但是從設計開始的時候就需要盡可能的考慮多的業(yè)務需求的可能性,這里有一個技巧,如果你不能確定你未來的需求增加,你應該保證盡量少的接口支持盡可能多的業(yè)務,不然到后期你會發(fā)現(xiàn)你的對外接口越來越多,一堆冗余接口;
2、接口可測試性,一些小的技巧可以讓你的 SDK 具備可測試性
- 為了測試,有時我們需要進行模擬,模擬 (mock) 類作為真實類的仿制類,它沒有真實操作,并且允許被重寫調用和驗證;
- 如果有些類是 final 的就很難模擬,并且是一個基于狀態(tài)的單例的話,就比較惡心了,這時候我們就需要考慮考慮在設計上盡量的規(guī)避.比如盡量避免單例,避免 final;
- 需要有測試用例,不管是開發(fā)人員還是測試開發(fā)人員都需要根據(jù)測試用例編寫。
3、API 的健壯性
- 大多數(shù)的開發(fā)者經常都是不耐煩的,他們看到很長時間都找不到出錯的原因是會有非常負面的情緒的,所以有一些錯誤應該盡早的拋出,這就好像比如你要 build 一個項目,如果一些錯誤能夠在編譯期間就暴露,一定好于完成編譯之后才出現(xiàn)錯誤.所以你需要寫清楚一些 exception 拋出給用戶;
- 盡量的保證接口的生命周期,如果是有序的需要在文檔說明。
五、優(yōu)秀的支持
如果以上四點你已經做得非常好了,這個時候你的文檔和技術支持直接就決定用戶是否選擇你的 SDK,也直接決定用戶對你的評級。所以好的支持就非常重要了,你需要建立開發(fā)者社區(qū),apple 文檔,javadoc ,readme甚至集成文檔,示例教程。
1、給對外暴露的代碼盡可能多的注釋,最好是相關聯(lián)的說明使用示例,比如你的這個接口跟另外一個接口是配套使用的;
2、需要有 demo 代碼,demo 代碼應該盡可能的簡單,讓使用的人可以遵循你的代碼進行嘗試,一定一定不要讓你的示例代碼寫的過于復雜,不要在無關緊要的交互模式上糾結,不然沒有用戶會花大量的時間去學習你的示例代碼,而且他們還會有很多疑問,或者 bug(解決方案除外);
3、如果有些接口需要廢棄,你應該添加廢棄的注解;
4、一定要有一個更新 list。清晰的版本更新日志.要相信不是所有的開發(fā)者會選擇最新版本的,你需要保證你的每一個版本都是穩(wěn)定可用的;
5、作為一個 SDK,你的功能一定不能是自己臆想出來的.你應該常常跟開發(fā)者交流,了解用戶的需求。每個功能都需要有客戶反饋作為依據(jù).
以上幾個點肯定不是建設一個偉大的庫的全部.只是我們在開發(fā)短視頻 SDK 的時候的一些思考.如果覺得有一定意義, 歡迎交流。
程序員客棧(proginn.com)—— 領先的中高端程序員自由工作平臺,未來企業(yè)的用人方式,更多文章請關注微信公眾號:程序員客棧Times(微信號:inntimes)
本文由作者投稿,如內容、圖片有任何版權問題,請小棧微信proginn處理。
