從零開始構(gòu)建一個Web項目:共享書吧

由于這個系列文章是用等同于開發(fā)中AOP模式的方式在寫, 所以一旦要涉及到具體項目開發(fā)的時候就會感覺出來混遲早要還的. 但是幸好, 完成一個項目, 寫代碼只不過是很小的一部分工作, 所以以下內(nèi)容涉及到代碼細節(jié)的部分, 我會用偽碼將邏輯說明清楚, 如果你有興趣正兒八經(jīng)的把這個項目做出來的話, 只需要用自己拿手的語言和框架來把詳細設(shè)計實施出來就行了.

項目的由來

老實說到處的例子都是做博客, BBS什么的, 既老套又無趣, 這個項目的來源是源于十幾年前大學時候自己一個真實的想法, 但是最終因為各種原因而沒有最終付諸實施, 所以這里當作一個示例項目, 用來詳細的跟大家講解一個項目如何從一個想法到最終成為大家使用的作品的完整過程.

共享書吧源于最樸素的網(wǎng)絡(luò)共享主義思想, 免費, 共享. 大家把自己擁有的已經(jīng)讀過的實體書, 通過一個平臺發(fā)布出來, 有需要的人, 只需要自己也發(fā)布一本書出來愿意供別人借去, 就可以去借自己需要的書. 你共享出來的書越多, 你能借到的書也越多.?

需求分析: 分拆場景, 寫User Story

什么是User Story?

User Story(使用者敘述)是一段簡單的功能敘述, 以客戶或者使用者的觀點寫下有價值的功能(functionality/feature). 與其說是規(guī)范文件, 不如說是代表客戶的一個需求而已, 因為具體實施的細節(jié)會延遲到開發(fā)的時候才會確定.

User Story 第一版

我們從用戶的角度來模擬一遍是如何使用這個設(shè)計都還沒有的系統(tǒng)的. 我們把自己當作用戶, 想象一下整個使用的過程:

U01: [用戶] 需要 注冊

U02: [用戶] 需要登入系統(tǒng)才能操作

U03: [用戶] 將自己的 [圖書] 登記

U04: [用戶] 登記的 [圖書] 需要將其設(shè)置為可借出, 才能被搜索到?

U05: [用戶] 登記過 [圖書] 后方可搜索別人登記并設(shè)為可借出的 [圖書]

U06: [用戶] 搜索到 [圖書] 后對其所有者發(fā)出 [借書申請]

U07: [用戶] 可以查看其他 [用戶] 發(fā)出的 [借書申請]

U08: [用戶] 在 [ 我收到的借書申請 ] 中 通過某用戶的 [ 借書申請 ]

U09:[用戶] 通過 [ 借書申請 ] 后將其設(shè)置為已經(jīng)借出

U10: [用戶] 收到 [圖書] 后設(shè)置為已經(jīng)到達

我在一邊寫的時候就將一些和系統(tǒng)的功能可能有關(guān)的詞都括起來了, 以便接下來的分析.

我們先把User Stories里面所有的名詞都抽取出來:

用戶, 圖書, 借書申請

然后找能和這些名詞關(guān)聯(lián)起來的其他詞, 我們得到了下面的概念圖:

概念模型

另說到工具的問題, User Stories基本上手寫卡片就OK了, 對, 就是很多高大上的外國開發(fā)團隊的照片里滿墻貼的便利貼上寫的就是, 需求分析就是從滿墻貼寫User Story的便利貼開始的.上面的概念圖呢其實也沒用什么專門的工具, 就是KeyNote, 如果不用Mac的話PowerPoint其實也是不錯的畫圖工具.別把時間浪費在找工具上, 用好手邊的東西就能做好分析工作了.

根據(jù)User Stories 生成 UE模型

UE是從用戶體驗的角度構(gòu)建模型-行為和UI之間的關(guān)聯(lián)的一種描述工具,?

做UE的工具很多, 但是最好的工具就是手邊的紙和筆, 因為一旦上了工具, 思維就會受到工具的限制, 而且其實UE模型的根本使用文字來描述的, 圖形只是方便直觀的理解. 所以接下來就用手繪拍照的方式. 本人字丑, 多擔待啦.?

注冊->登錄

注冊->登錄

登錄->我的圖書

登錄->我的圖書

我的圖書->添加圖書

我的圖書->添加圖書

添加圖書->待借出圖書

添加圖書->待借出圖書

待借出圖書->我的借出申請

待借出圖書->我的借書申請

通過申請->寄出圖書

通過申請->寄出圖書

上面的UE需要經(jīng)過反復驗證, 我們這里就跳過這個步驟了, 驗證的目的在于兩個點:

1) 驗證有無邏輯上的斷點, 比如狀態(tài)推進到一些地方就走不通了.

2) 驗證操作上有沒有多余繁復的操作, 盡量簡化, 同時也就是簡化了用戶交互的過程

因為跳過了驗證過程, 所以上面我們第一稿的UE是有問題的, 主要是邏輯上不夠全面, 有重復的地方, 所以留下一個問題, 由讀者自行去完成第二版. 這也是一個鍛煉產(chǎn)品能力的練習方法.

定稿后, 我們就可以通過UE來生成3個后續(xù)的生成物: UI/UX, 實體模型, 控制器結(jié)構(gòu)

UI/UX 我們暫且跳過, 這個不在本系列討論范疇, 一般網(wǎng)站出到UI就可以了, App的話最好是UI和UX都要出.

UE生成實體模型到數(shù)據(jù)表結(jié)構(gòu)

基本的方式是, 對UE中, 和實體關(guān)聯(lián)的名字都拿出來分析是不是屬于實體的屬性, 比如和用戶關(guān)聯(lián)的有 郵箱地址, 登錄密碼, 收貨地址. 有一些屬性是根據(jù)經(jīng)驗加入的, 比如用戶的昵稱, 頭像, 還有狀態(tài)

圖書的屬性在簡化的線框UE并沒有完全提現(xiàn), 我們可以根據(jù)實際的數(shù)據(jù)來源來分析, 比如我們打算通過ISBN號直接從豆瓣抽取圖書信息, 那么根據(jù)豆瓣的頁面

圖書屬性

根據(jù)上圖我們可以抽取出圖書的屬性列表.

最后得到實體模型如下圖:

實體模型圖

根據(jù)之前的文章我們將用戶拆分成兩個表, 然后呢, 1-n, n-n 這些關(guān)系都需要中間關(guān)系表來支撐,最后我們得到了數(shù)據(jù)表結(jié)構(gòu)如下圖:

數(shù)據(jù)庫表結(jié)構(gòu)

UE生成控制器結(jié)構(gòu)

通過UE的我們可以將頁面和按鈕事件, 轉(zhuǎn)化成action, 然后每個action對應(yīng)到一個控制器, 這里對控制器我們用URL來表示.

注冊/登錄

注冊登錄

我的圖書/添加圖書

我的圖書/新增圖書

待借出圖書/搜索可借圖書

待借出圖書/搜索可借圖書

我要借書/借書申請

我要借書/借書申請

寄出圖書

寄出圖書

設(shè)計進行到這一步已經(jīng)相當?shù)慕咏毠?jié)了, URL的設(shè)計風格不盡相同, 其實也沒有強制的什么規(guī)范, 流行的Restful風格的URL設(shè)計更適合API, 而網(wǎng)頁因為有的頁面承載了多個功能, 所以在語義上并不是很契合, 這個問題我們后面會找個章節(jié)來詳細說明一下.

剩下的工作就開始正式進入了寫代碼的階段了. 下面的內(nèi)容更多的偏向于小白了, 因為有過一定項目經(jīng)驗的同學已經(jīng)可以通過上面的內(nèi)容掌握如何開發(fā)一個Web項目了.

開發(fā)階段

因為大家用的Web框架不一樣, 所以開發(fā)階段的細節(jié)都是不盡相同的, 所以我們這里抽象開發(fā)階段的共性問題來討論. 你可以將里所使用的Web框架和本文內(nèi)容做比對, 或者將本文作為一個Guide來使用.

在實際的編碼階段, 我們就需要將前面所有的設(shè)計用代碼的形式表達出來. 下面我們用偽碼來詳細說明一下每一個部分我們要做一些什么.

注冊/登錄

注冊: /regist GET

直接返回靜態(tài)的注冊頁面

點擊注冊按鈕: /regist POST

1) 驗證輸入?yún)?shù) email, password和address, 判斷非空和email符合郵箱地址規(guī)范

2) 通過email在UserLogin表查詢有無記錄, 有記錄返回錯誤: 該email已經(jīng)注冊了

3) hash密碼后加鹽二次hash生成存儲的密碼

4) UserLogin表插入記錄, User表插入記錄

5) 轉(zhuǎn)跳頁面到登錄頁

登錄: /login GET

返回登錄靜態(tài)頁

點擊登錄按鈕: /login POST

1) 驗證輸入?yún)?shù) email, password, 判斷非空

2) 查詢UserLogin表email等于輸入?yún)?shù)email的記錄, 為空就返回錯誤

3) userlogin記錄的password字段里獲取鹽值和二次hash的值, 輸入password進行hash后用鹽值二次hash后和記錄里的二次hash值對比, 不等則返回錯誤

4) 生成登錄token寫入cookie

5) 轉(zhuǎn)跳到我的圖書頁面

我的圖書: /books GET

查詢UserBooks表條件是user_id等于登錄用戶的user_id, 獲取到的記錄用模板渲染圖書列表后返回

添加圖書: /books/new GET

返回添加數(shù)據(jù)的靜態(tài)頁面.

檢測ISBN按鈕: /books/isbn POST

1) 驗證輸入ISBN號(長度)

2) 在Book表中通過ISBN查詢系統(tǒng)內(nèi)有無該本圖書, 如果有, 返回圖書json

3) 通過豆瓣API, 用ISBN獲取圖書信息

4) 返回圖書json

添加圖書按鈕: /books/new POST

1) 驗證輸入ISBN號(長度)

2) 在Book表中通過ISBN查詢系統(tǒng)內(nèi)沒有該本圖書

3) 通過豆瓣API, 用ISBN獲取圖書信息

4) 插入Book表

5) 在UserBooks表中查詢用戶有無這本書

6) 如果沒有, 插入UserBooks表

待借出的書: /books/unborrow GET

在UserBooks獲取用戶處于未借出狀態(tài)的圖書, 通過模板渲染圖書列表輸出

設(shè)置為可借出: /book/<user_book_id>/ PUT

1) 根據(jù)參數(shù)state為可借出就繼續(xù)執(zhí)行

2) 設(shè)置狀態(tài)為可借出

設(shè)置為不可借出: /book/<user_book_id>/ PUT

1) 根據(jù)參數(shù)state為不可借出就繼續(xù)執(zhí)行

2) 設(shè)置狀態(tài)為不可借出

查詢可借圖書: /books/search POST

1) 檢測參數(shù)key, 判斷不能為空

2) 通過book表的屬性, 模糊查詢, 返回狀態(tài)為可借出的圖書

3) 通過模板渲染輸出圖書列表

我要借書按鈕: /book/<user_book_id>/ PUT

1) 檢測輸入屬性state為提交申請就繼續(xù)執(zhí)行

2) 檢測用戶對該書有沒有提交過借書申請

3) 設(shè)置狀態(tài)為提交借書申請

4) 在Request表插入記錄

我的借書申請: /books/borrow/request/me GET

在Request表用user_id等于登錄用戶user_id的條件查詢登錄用戶發(fā)起的借書申請, 渲染圖書列表返回

我收到的借書申請: /books/borrow/request/tome GET

在Request表join UserBooks表根據(jù)UserBooks表的user_id屬性查詢用戶收到的的借書申請, 渲染圖書列表返回

通過申請按鈕: /book/<user_book_id>/?PUT

1) 檢測輸入屬性state為通過申請就繼續(xù)執(zhí)行

2) 設(shè)置圖書狀態(tài)為通過申請

待寄出圖書列表: /books/unsended GET

在Request表里獲取狀態(tài)為待寄出的圖書列表, 渲染圖書列表返回

保存快遞信息: /book/<user_book_id>/ PUT

1) 檢測輸入屬性里有sn就繼續(xù)執(zhí)行

2) 保存快遞記錄到Request表

設(shè)置為到貨: /book/<user_book_id>/ PUT

1) 檢測輸入屬性state為到貨

2) 將申請狀態(tài)設(shè)置為到貨

3) 將UserBooks的user_id修改為新的user_id


故事到了這里就進入尾聲了, 你如果跟著一路做下來相信項目已經(jīng)做得七七八八了, 但是你還有問題, 用戶怎么修改密碼呀? 怎么換頭像啊? 怎么找回密碼呀? 相信你跟全文走完全流程應(yīng)該能自己補全剩下的部分了.

這個時候你已經(jīng)搞定了第一版的程序, 接下來就可以上線運營了. 如果你運氣很好, 用戶量刷刷的上升, 那么很快你就會遇到新的問題了. 下一章我們繼續(xù)這個故事

to be continue...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容