版權聲明:本文原創發布于公眾號 wingjay,轉載請務必注明出處! http://www.lxweimin.com/p/39dce598faf1
我是wingjay,軟件工程師,現居上海。
這次來記錄下自己獨立全端開發的第一款side project——簡詩 2.0——及其中的一些心路歷程和踩坑經驗。
緣由
一年前我花了一兩天時間開發了一款自認為挺cool挺優雅的Android應用,濃郁的中國風色彩和極簡的設計風格,是我開發簡詩最根本的原因,當時還在簡書上寫過一篇文章《如何在一天之內完成一款具備cool屬性的Android產品<簡詩>》,獲得了不少讀者的喜愛。不過,當時的版本只有 Android 端,沒有服務器來支持數據存儲。因此,今年又重新開發服務端,一方面為喜愛簡詩的用戶帶來更多有趣的功能,另一方面鍛煉下個人技術。
簡詩最初設計草稿來自《Producter》一書,設計思路獨特:別致的中國風縱書體驗,大片留白的日式設計理念,體現濃郁傳統中國文化的細節,都使得簡詩與眾不同。
開發一款如此別具一格的 App,在我看來,是一件非常酷的事情。
富有挑戰而有趣的全端開發
簡詩的開發主要包括三方面:設計、Android 端、服務端。
設計
我在最初《Producter》的設計草稿基礎上,我對整個使用體驗做了進一步優化:
- 剔除了原始選擇年、月、日的步驟;
- 在首頁添加實時變化的三行小詩;
- 在撰寫頁面根據當前時間如正午、夜半,顯示不同的提示語以讓用戶感覺更為親近;
- 支持更換背景顏色,色值取自中國傳統顏色如素、月白、水紅等;
- 文章列表頁面仿照古代書籍目錄設計;
- 分享時會自動生成簡詩的印章,借鑒了傳統書畫作品中的印章;
- 首頁添加實時變化背景圖片,這些圖片均來自全球優質的攝影作品 UnSplash 網站。
Android 端
Android 端采用了當前最為流行的移動架構和依賴,運行穩定,代碼結構簡潔,crash 率只有 0.1% ~ 0.3%。
開發過程中主要遇到一個問題是客戶端與服務器之間進行數據同步,由于一個用戶同時具有本地數據庫和遠程數據庫,所以一旦數據庫之間出現偏差,就可能導致用戶數據丟失,而且要能夠保證用戶多客戶端、離線修改數據、同步失敗等情況下,都必須保證數據的可靠性,防止數據丟失。這種多數據庫同步一向是較為復雜麻煩的,不過為了能讓用戶在沒有網絡時仍然能使用簡詩,我還是花了一些去填好這個坑。
經過一段時間的摸索,目前簡詩的代碼里已經能很好的支持數據同步了,基本思想是:
- 用戶首次登陸簡詩,會嘗試去server取歷史數據(如果是新用戶則取到為空),返回數據的同時會返回一個sync_token,里面包含了當前時間戳;
- 收到數據后,客戶端把數據存儲到本地數據庫(如果為空則不存),同時把sync_token存儲起來給下一次同步用;
- 在簡詩使用時,會把用戶所有與數據庫相關的操作:create、update、delete按順序存儲在本地一張表里;
- 在網絡正常的情況下,客戶端會定期將這些操作上傳給服務器,同時帶上之前的sync_token;
- 服務器接收到這些數據后,把這些crud操作依次執行一遍即可更新到當前客戶端最新數據;那么,如果用戶在這期間通過別的客戶端更改過數據庫呢?
- 這時我們會基于sync_token里上一次同步的時間,去數據庫找出所有晚于這個時間的操作,同樣拼接成crud的json串;然后把這個json數據和新的sync_token(基于當前時間)回傳給客戶端,其中還包括一個成功sync到數據庫的數量synced_count;
- 客戶端收到{synced_count:{..}, crud:{..}, sync_token:{..}}后,首先根據synced_count把歷史的操作表刪除對應的紀錄,即刪除已經成功sync了的操作;crud:可以更新本地數據庫,如果有其他客戶端更改的可以同步進來;sync_token下次sync時使用。
這樣大體可以實現一個完善的客戶端和服務器的數據庫同步操作,而且支持多客戶端更改,并保證本地數據的最新。
當然,Android版里面還有不少較為復雜的技術點,以后再細說吧。
服務端
本人之前有完整的 PHP 后端開發經驗,所以如果采用 PHP 開發的話難度會小很多;不過我最終選擇了自己不熟悉的 Python 來進行服務端開發,這給我帶來了一些挑戰。
之所以采用 Python 有兩個原因:一是對 Python 這門語言的好奇,軟件工程師總是對未知領域充滿好奇并想去探索;二是希望通過不同語言的服務端開發,來提升自己對服務端架構的理解。
在開發過程中我重新學習實踐了一款優秀的Python框架:Flask的設計思想,也熟悉了阿里云服務器+nginx+gunicorn+supervisor的服務器運行環境,MySql + Redis的數據存儲架構,寫了一些腳本來運行數據庫命令、完整的unit-test。
另外做了一些有趣的嘗試:利用Slack + Jenkins 工具搭配,只要在Slack里輸入一句命令,就會自動把服務器代碼從GitHub部署到阿里云服務器上,比起以前手動拷貝代碼到ftp上簡直cool太多了。
當然,后端開發是非常有趣的,后面還會投入更多精力來搭建更加完善、穩定的后端環境,嘗試更多有意思的玩法。
其實,我覺得side project最大的困難不在于技術,而在于懶,哈哈
其實你有很多時間來做side project
我相信很多人和我一樣,對side project很感興趣,希望能利用業余時間去開發自己感興趣的項目,提高技術和實踐水平。那么,衡量好時間精力分配就比較重要了。
作為一名全職軟件工程師,簡詩 v2.0 的開發主要利用我周末的時間。總共花了三到四個周末,即六天到八天左右,完成了 Android 版本和服務端的開發。開發后段我的一位好友:Ray 也加入并協助進行了部分開發工作,有幾個周六我倆都開發到了大概凌晨四點鐘左右,一邊闡述自己的產品創意,一邊討論工程實踐的可行性,是非常有趣的一段經歷。
簡詩2.0發布后,我準備重新梳理下服務端的整理架構,深入學習Flask的設計思想,然后對服務端做一些改進。當然仍然是利用晚上和周末的時間。
讓大家知道你的side project
酒香不怕巷子深,這句話在現在可能并不是那么適用了。我見過不少做的很爛的app廣受歡迎,也見過很多優秀的app默默無聞。我當然明白很多工程師不愿甚至不屑去推廣宣傳,認為只要自己的東西牛逼,遲早會有一大堆人簇擁過來。
但是,移動開發日益激烈的今天,每天都有無數新的app誕生,人們不會愿意花時間下載嘗試一款沒聽說過的app。
在國內,我們可以嘗試下面的一些渠道來推廣自己的作品:
- v2ex 里面有很多不吝贊賞的讀者,大家會對認真的作品給予認可和鼓勵,也會對虛有其表的項目表示呵呵;
- 應用推薦平臺:最美應用、少數派、AppSo等,當然要有一定的實力才能入選哦;
- 應用商店:酷安、小米、豌豆莢等應用商店如果能給你一個好的位置,肯定會帶來非常多用戶的。
全棧工具推薦
在開發中我應用到了當今很流行的工具,這里給大家介紹一些我認為很有用的工具或者代碼框架。
- 設計
- Zeplin:在dev與designer之間共享設計稿;
- Sketch:強大的移動應用設計工具,什么都能做;
- 字體:文悅科技家有很多優秀的字體;
- dribbble:全球最優質的設計作品聚集地。
- Android
- OkHttp + Retrofit + RxJava + RxAndroid + RxLifecycle:為你的應用提供簡潔穩定的網絡架構;
- Dagger:依賴注入框架,性能好;
- Fabric:監控應用的crash情況和用戶增長,免費;
- Stetho: 方便在chrome里監聽所有http請求,查看本地Database內容等;
- DBFlow: 基于Sqlite的orm工具。
- Server
- Python + Flask:快速為移動應用搭建穩定安全的后臺服務;
- Jenkins:當前最好用的持續集成工具,自動將GitHub代碼部署到服務器上,再也不用copy代碼到ftp上啦;
- Rollbar / Sentry + Slack:監控server運行環境,一旦發生問題能及時通知給開發者停下手中的游戲去修bug;
- Sequel Pro:好用簡潔的數據庫管理工具;
- Redis:提供高速鍵值對存儲查詢服務。
- 技術資訊:
- Airb&b、Square、Facebook家的tech blog,最新的技術來自那里
- Medium+稀土掘金+灣區日報:閱讀優質技術文章
小結
當代的人們逐漸習慣于閱讀快速的文字片段,淡忘了寫作的體驗。而簡詩的存在,就是希望讓人們重新找回文字的美好之處,重新感受寫作的樂趣。或許并非所有人都喜歡簡詩,但只要有一部分人,能從簡詩里重新感受到文字的溫暖,就足夠了。
GitHub 開源地址,包括 Android 與 Server: https://github.com/wingjay/jianshi
作為一名開發者,我也熱愛并重視產品設計。平日里會閱讀一些如日式設計相關的書籍。不過,我深知自己在設計方面的學識淺的可憐,因此,我希望在業余時間里能和一些優秀的設計師合作,共同開發一些獨具匠心的產品給大家使用。
歡迎通過簡書聯系我。
謝謝!
wingjay