乙個小功能讓我懂得了設計模式的重要性

2021-07-24 10:53:25 字數 2111 閱讀 5673

leader讓我開發乙個專案排期的功能,乙個看似很簡單的功能,我卻栽了坑,並從中學到了設計模式及演算法的重要性。

一、功能點

目前平台已有專案管理功能,需要增加乙個專案排期的功能,其實就兩個頁面,乙個排期的編輯頁面,乙個按照團隊展示團隊人員專案排期的甘特圖。

二、原來做法

我不怎麼會前端,一開始把精力都放在前端甘特圖繪製上了,忽略了設計的重要性。

我只是簡單的建了一張表,把專案、人員、排期一股腦放在了一張表裡,與專案表、人員表存在緊耦合,不符合資料庫設計原則。表結構如下

idschedule_name

schedule_duration

start_time

end_time

staff_name

project_id

project_name

note

1開發設計

42016-10-20

2016-10-28

張三,李四,趙紅

21專案一

開發開發

2測試評審

62016-10-29

2016-11-12

小張,小王

100專案二

測試測試

這樣設計表時,排期的增刪改查很容易,就按照上圖一輸入的填寫的資料表裡就可以。但是在第二個頁面,按照團隊展示時,就遇到問題了,先查到團隊下所有的人員,然後乙個for迴圈,不停的http請求去獲取每個人的排期,效能很差,後來我的做法是取出所有的人員,取出所有的排期,**裡面處理邏輯,這樣滿足基本需求,時間複雜度為o(n*m)

三、新需求

後來leader提出新的要求,要求對每個人下面的排期進行分組,時間上沒有交集的排期放在乙個分組,我在原來的處理邏輯迴圈裡,對每個人的任務進行乙個分組處理,分組處理的時間複雜度為o(t*t),再加上外層的迴圈,複雜度為o(m*n*t*t)。頁面展示根本刷不出來,一直超時。但是基於上面的表結構設計,又沒辦法優化演算法。

四、重構

不得已,必須進行重構。

(1)拆表

首先是拆表,按照資料庫設計規範,即那幾個正規化

第一正規化:要求所有的域都應該是原子性的。我原來的設計,staff_name一列放n多人名,其實是不合理的

第二正規化:要求資料庫表中的每個例項或記錄必須是可以唯一的區分

第三正規化:要求乙個關係中不包含已在其他關係已包含的非主鍵字資訊。如我上面的表中,project_name,staff_name都是非主關鍵字,不應該出現在排期表中。

於是,將上面的表拆成兩張表

排期表id

schedule_name

schedule_duration

start_time

end_time

project_id

note

專案表主鍵

通過project_id與專案表關聯

排期-人員關係表

idschedule_id

staff_id

gmt_time

人員表主鍵

通過schedule_id與排期表關聯

通過staff_id與員工表關聯

(2)使用事務

拆成多個表後,為了保證資料的一致性,就要使用事務,只有一部分成功時要進行回滾,當所有的操作都ok時,才commit

(3)通過mysql的一些函式及用法,減少業務**量

主要使用了concat、group_concat、ifnull函式,使用了多表查詢,使用了group by等用法

使用group_concat時還遇到乙個小問題,就是group_concat有個預設長度是1024,超過這個長度字串會被截斷,可以通過設定group_concat_max_len=-1為不限制長度。

(4)優化演算法

對於那個新需求,對排期分組,我原來的演算法複雜度是o(t*t),將其優化為o(t)

這樣,經過上面操作後,時間複雜度由原來的o(m*n*t*t)變成了o(m*t),效能大大提公升。

心得體會:處處皆學問,做任何事情前都得思考!

做乙個拖拽的小功能

做了乙個拖拽功能,感覺有點卡頓。思路比較簡單,滑塊拖動的時候限制邊界條件就好了,完整 如下 拖拽 title style divclass drag style head body div class div class divclass drag div div script window.onl...

我學習設計模式的乙個總結

記憶裡是從2010年開始學習 使用設計模式的,之前都是把所有的東西堆到乙個類裡。總的來說,使用設計模式後對寫的 比較容易理解,修改bug時影響的範圍會縮小很多。設計模式在gof中被分為三類 一,創造型 二,結構型 三,行為型 各種軟體設計思想解決的問題都是 解耦和重用。在創造型中,一共有五個模式 1...

實現乙個程式登入時長限制的小功能

受專案的需求,需要實現程式臨時使用一段時間且25天後再次登入就不能再使用,基於vc 使用的方法是通過讀寫登錄檔的首次登入時間和最近登入時間來實現記錄天數,從而實現該功能。void limitloginbyreg 第一次登入時間 cstring strtimefirst ctime timefirst...