1,項目簡介
本課題主要是基於VUE和SpringBoot框架實現一個抽獎系統服務端,該抽獎平台是一個支持多種不同的抽獎方式且支持高並發的多種用戶系統,抽獎系統角色共分為四類,包括基礎的抽獎用戶,抽獎發布者,進行數據信息管理的后端管理員以及自動執行抽獎的抽獎執行模塊。普通用戶可以查看並參加抽獎;抽獎發布者可以發布抽獎,管理自己發布的抽獎信息和參加該抽獎的用戶,獲取系統返回的中獎用戶並發獎;管理員可以通過抽獎系統后端管理現有的抽獎及用戶信息;抽獎執行模塊則負責自動適時執行各類抽獎。
2,開發環境
前台開發平台:web前端
后台開發平台:IntelliJ IDEA
數據庫:MySQL & Redis
服務器:雲服務器(BAE或SAE)
計算機硬件配置:
抓取服務器:內存1.5G以上
數據服務器:內存2G以上
3,使用的技術
前端:vue
后端
web框架:Springboot
持久層框架:JPA
認證授權框架:Shiro
分布式框架:Dubbo+Zookeeper
搜索框架:ElasticSearch
數據庫:
mysql+redis
4,設計模式
4.1 八大設計原則
提到設計模式,我們首先需要了解設計模式的設計原則。
-
-
高層模塊(穩定)不應該依賴於低層模塊(變化),二者都應該依賴於抽象(穩定)。
-
抽象(穩定)不應該依賴於實現細節(變化),實現細節(變化)應該依賴於抽象(穩定)。
-
-
開放封閉原則(OCP)
-
對擴展開放,對更改封閉。
-
類模塊應該是可以擴展的,但是不可修改。
-
-
單一職責原則(SRP)
-
一個類應該僅有一個引起它變化的原因。
-
變化的方向隱含着類的責任。
-
-
Liskov替換原則(LSP)
-
子類必須能夠替換它們的基類(IS-A)。
-
繼承表達類型抽象。
-
-
接口隔離原則(ISP)
-
不應該強迫客戶程序依賴它們不用的方法。
-
接口應該小而完備。
-
-
優先使用對象組合,而不是類繼承
-
類繼承通常為"白箱復用",對象組合通常為"黑箱復用"。
-
繼承在某種程度上破壞了封裝性,子類父類耦合度過高。
-
而對象組合則只要求被組合的對象具有良好定義的接口,耦合度較低。
-
-
封裝變化點
-
使用封裝來創建對象之間的分界層,讓設計者可以在分界層的一側進行修改,而不會對另一側產生不良的影響,從而實現層次間的松耦合。
-
-
針對接口編程,而不是針對實現編程
-
不將變量類型聲明為某個特定的具體類型,而是聲明為某個接口。
-
客戶程序無需獲知對象的具體類型,是需要知道對象所具有的接口。
-
-
4.2 重構關鍵技法
-
-
早綁定 -> 晚綁定
-
繼承 -> 組合
-
編譯時依賴 -> 運行時依賴
-
一般的new 違背了 依賴倒置原則(依賴抽象,而不依賴具體)
例:A a = new A(); //此處的A是一個具體的類,而不是抽象
根據依賴倒置原則,我們應該盡可能的使用抽象設計,減少具體(可以降低耦合),但是抽象類是不可以實例化的(new),此時就需要一種方式來解決實例化問題。提供一個工廠接口,把創建對象的任務往后推給子類,使當前類與new隔離。該種設計模式就是工廠模式。
使用工廠模式的好處:工廠模式用於隔離類對象的使用者和具體類型之間的耦合關系。面對一個經常變化的具體類型,緊耦合關系(new)會導致軟件的脆弱。一旦更改具體類型,就要更改使用者中的代碼,耦合度太高,而工廠方法,降低了兩者的耦合度,類型改變或增加時只需改變/增加工廠子類即可,而使用者的源碼不必改變。
工廠模式的通用類圖結構圖:(附部分注釋,希望可以幫助讀者快速理解)

5,架構風格
5.1 微服務架構
1,提升開發交流,每個服務足夠內聚,足夠小,代碼容易理解;
2,服務獨立測試、部署、升級、發布;
3,按需定制的DFX,資源利用率,每個服務可以各自進行x擴展和z擴展,而且,每個服 務可以根據自己的需要部署到合適的硬件服務器上;每個服務按需要選擇HA的模 式,選擇接受服務的實例個數;
4,容易擴大開發團隊,可以針對每個服務(service)組件開發團隊;
5,提高容錯性(fault isolation),一個服務的內存泄露並不會讓整個系統癱瘓;
6,新技術的應用,系統不會被長期限制在某個技術棧上;
5.2 分布式架構
| 請求URI | 請求方式 | |
|---|---|---|
| 查詢所有活動 | activitys | GET |
| 查詢某個活動(來到修改頁面) | activity/1 | GET |
| 來到添加頁面 | activity | GET |
| 添加活動 | activity | POST |
| 來到修改頁面(查出活動進行信息回顯) | activity/1 | GET |
| 修改活動 | activity | PUT |
| 刪除活動 | activity/1 |
6,接口設計
6.1 用戶界面
在用戶抽獎界面以及抽獎發布者的界面,應充分考慮展示信息與用戶的可交互性,在需求分析的基礎上,合理展示抽獎系統為用戶提供的各種信息,包括根據用戶推薦的各類抽獎活動。由於前端確定采用VUE框架,因此可以基於VUE對信息進行簡單排布形成基本的展示界面,再在此基礎上進一步優化,盡可能降低界面和操作的學習成本。
6.2 軟件接口
前端方面,可以提供前端數據接口用於接收抽獎系統服務端發送的用於顯示的信息,提高前端界面的可擴展性,也易於更換或者直接擴展前端界面。服務器端則提供基本的數據庫的連接接口,方便數據庫的遷移、升級和更換;另外還可以提供抽獎執行模塊、發獎模塊的接口,實現模塊化,模塊之間進行解耦以提高維護性和可擴展性。
7,UML類圖

8,視圖
8.1,分解視圖
分解是構建軟件架構模型的關鍵步驟,分解視圖也是描述軟件架構模型的關鍵視圖,一般分解視圖呈現為較為明晰的分解結構(breakdown structure)特點。分解視圖用軟件模塊勾划出系統結構,往往會通過不同抽象層級的軟件模塊形成層次化的結構。

8.2,依賴視圖
依賴視圖展現了軟件模塊之間的依賴關系。比如一個軟件模塊A調用了另一個軟件模塊B,那么我們說軟件模塊A直接依賴軟件模塊B。如果一個軟件模塊依賴另一個軟件模塊產生的數據,那么這兩個軟件模塊也具有一定的依賴關系。依賴視圖在項目計划中有比較典型的應用。比如它能幫助我們找到沒有依賴關系的軟件模塊或子系統,以便獨立開發和測試,同時進一步根據依賴關系確定開發和測試軟件模塊的先后次序。依賴視圖在項目的變更和維護中也很有價值。比如它能有效幫助我們理清一個軟件模塊的變更對其他軟件模塊帶來影響范圍。

8.3,泛化視圖
泛化視圖展現了軟件模塊之間的一般化或具體化的關系,典型的例子就是面向對象分析和設計方法中類之間的繼承關系。值得注意的是,采用對象組合替代繼承關系,並不會改變類之間的泛化特征。因此泛化是指軟件模塊之間的一般化或具體化的關系,不能局限於繼承概念的應用。泛化視圖有助於描述軟件的抽象層次,從而便於軟件的擴展和維護。比如通過對象組合或繼承很容易形成新的軟件模塊與原有的軟件架構兼容。

8.4,執行視圖
執行視圖展示了系統運行時的時序結構特點,比如流程圖、時序圖等。執行視圖中的每一個執行實體,一般稱為組件(Component),都是不同於其他組件的執行實體。如果有相同或相似的執行實體那么就把它們合並成一個。執行實體可以最終分解到軟件的基本元素和軟件的基本結構,因而與軟件代碼具有比較直接的映射關系。在設計與實現過程中,我們一般將執行視圖轉換為偽代碼之后,再進一步轉換為實現代碼。

8.5,實現視圖
實現視圖是描述軟件架構與源文件之間的映射關系。比如軟件架構的靜態結構以包圖或設計類圖的方式來描述,但是這些包和類都是在哪些目錄的哪些源文件中具體實現的呢?一般我們通過目錄和源文件的命名來對應軟件架構中的包、類等靜態結構單元,這樣典型的實現視圖就可以由軟件項目的源文件目錄樹來呈現。
實現視圖有助於碼農在海量源代碼文件中找到具體的某個軟件單元的實現。實現視圖與軟件架構的靜態結構之間映射關系越是對應的一致性高,越有利於軟件的維護,因此實現視圖是一種非常關鍵的架構視圖。

8.6,部署視圖
部署視圖是將執行實體和計算機資源建立映射關系。這里的執行實體的粒度要與所部署的計算機資源相匹配,比如以進程作為執行實體那么對應的計算機資源就是主機,這時應該描述進程對應主機所組成的網絡拓撲結構,這樣可以清晰地呈現進程間的網絡通信和部署環境的網絡結構特點。當然也可以用細粒度的執行實體對應處理器、存儲器等。
部署視圖有助於設計人員分析一個設計的質量屬性,比如軟件處理網絡高並發的能力、軟件對處理器的計算需求等。

8.7,工作任務分配視圖
工作分配視圖將系統分解成可獨立完成的工作任務,以便分配給各項目團隊和成員。工作分配視圖有利於跟蹤不同項目團隊和成員的工作任務的進度,也有利於在個項目團隊和成員之間合理地分配和調整項目資源,甚至在項目計划階段工作分配視圖對於進度規划、項目評估和經費預算都能起到有益的作用。

9,數據庫設計
用戶數據模型:User_table
| 屬性 |
類型 |
鍵值 |
注釋 |
| Id |
Int |
主鍵 |
記錄id |
| name |
String |
- |
用戶名 |
| password |
String |
- |
密碼 |
| tell |
String |
- |
電話 |
| address |
String |
- |
地址 |
登錄/注冊數據模型:Login_table
| 屬性 |
類型 |
鍵值 |
注釋 |
| Id |
Int |
主鍵 |
記錄id |
| Name |
String |
- |
用戶名 |
| Password |
String |
- |
密碼 |
獎品數據模型:goods_table
| 屬性 |
類型 |
鍵值 |
注釋 |
| Id |
int |
主鍵 |
記錄id |
| name |
String |
- |
獎品名稱 |
| color |
String |
- |
顏色 |
| Price |
Float |
- |
價格 |
抽獎活動數據模型:activity_table
| 屬性 |
類型 |
鍵值 |
注釋 |
| Id |
int |
主鍵 |
記錄id |
| name |
String |
- |
活動名稱 |
| gId |
int |
外鍵 |
關聯獎品表 |
| startTime |
Date |
- |
開始時間 |
| stopTime |
Date |
- |
結束時間 |
| pName |
String |
- |
發布者姓名 |
| pTell |
String |
- |
發布者電話 |
| pAddress |
String |
- |
發布者地址 |
join_table:中獎榜單
| 屬性 |
類型 |
鍵值 |
注釋 |
| Id |
int |
主鍵 |
記錄id |
| userId |
int |
外鍵 |
中獎用戶編號 |
| activityId |
int |
外鍵 |
活動編號 |
| goodName |
String |
- |
獎品名稱 |
| goodPrice |
float |
- |
獎品價格 |
發布者發布活動
| 屬性 |
類型 |
鍵值 |
注釋 |
| Id |
int |
主鍵 |
記錄id |
| publisherId |
int |
外鍵 |
發布者編號 |
| activityId |
int |
外鍵 |
活動編號 |
10,系統工作機制
用戶通過登錄進入該系統,進入后可以查看並參加各種抽獎活動,抽獎活動分為實時抽獎和定時開獎兩種。參加實時抽獎的用戶可以立即獲取中獎信息;參加定時開獎的用戶需要等開獎之后才可以查看中獎信息。用戶中獎后,需要填寫物流信息。抽獎發布者可以實時更改中獎概率,比如人少時,減少獎品投放,人多時增加獎品投放。管理員負責管理監視系統,比如系統的負載情況,或者是否存在違規活動等。
參考文獻:
https://gitee.com/mengning997/se
https://www.bilibili.com/video/BV1kW411P7KS?p=5
https://blog.csdn.net/sinat_34166518/article/details/89206059
https://www.zhihu.com/question/65502802/answer/615568011
