軟件工程課設(shè)實(shí)戰(zhàn):從需求到測(cè)試全流程解析)
簡(jiǎn)介中小型賓館管理系統(tǒng)的軟件工程課程設(shè)計(jì)報(bào)告系統(tǒng)梳理了需求概述、設(shè)計(jì)概要及實(shí)施策略面向軟件工程專業(yè)學(xué)生和課程設(shè)計(jì)實(shí)踐者旨在解決訂房、住宿、退房等環(huán)節(jié)手工管理效率低的問題。報(bào)告結(jié)合賓館業(yè)務(wù)實(shí)際從技術(shù)可行性、經(jīng)濟(jì)可行性和運(yùn)行可行性展開分析明確預(yù)訂管理、入住登記、房間狀態(tài)更新、賬單計(jì)算與退房處理等核心功能需求并繪制數(shù)據(jù)流圖與數(shù)據(jù)字典建立系統(tǒng)模型。設(shè)計(jì)部分采用模塊化原則劃分用戶模塊、客房模塊、預(yù)訂模塊、賬務(wù)模塊同時(shí)提出基于C#與SQL Server的界面與數(shù)據(jù)庫實(shí)現(xiàn)方案。資源為單份doc格式文檔壓縮包約862KB報(bào)告結(jié)構(gòu)完整目錄層級(jí)清晰適合作為同類管理信息系統(tǒng)課程設(shè)計(jì)的寫作參考。目前已有4670人學(xué)習(xí)下載讀者可從中借鑒需求分析框架、模塊化設(shè)計(jì)方法以及文檔組織規(guī)范幫助完成高質(zhì)量課程設(shè)計(jì)報(bào)告。1. 選題即需求這份軟件工程課程設(shè)計(jì)為什么落在中小型賓館管理系統(tǒng)上軟件工程課程設(shè)計(jì)最難的不是寫代碼而是找一個(gè)“業(yè)務(wù)邊界清晰、數(shù)據(jù)流完整、能撐起整套流程文檔”的題目。中小型賓館管理系統(tǒng)恰好是最耐打的選擇訂房、入住、退房、換房、結(jié)算、押金每個(gè)環(huán)節(jié)都能對(duì)應(yīng)到真實(shí)前臺(tái)的一個(gè)具體動(dòng)作也都能落成需求分析、數(shù)據(jù)字典、E-R 圖和測(cè)試用例。我當(dāng)時(shí)做模擬項(xiàng)目X之前去某賓館前臺(tái)蹲了一圈發(fā)現(xiàn)他們還在用手工臺(tái)賬登記房態(tài)12 點(diǎn)該退房靠人喊押金和房費(fèi)經(jīng)常對(duì)不上賬。這個(gè)小場(chǎng)景比任何虛擬題都更能說明“為什么要做系統(tǒng)”。這套方案面向正在寫課程設(shè)計(jì)報(bào)告、或者要交付一套 C/S 結(jié)構(gòu)管理系統(tǒng)的同學(xué)從可行性分析一路走到數(shù)據(jù)庫設(shè)計(jì)、測(cè)試與答辯驗(yàn)收每一章都有可直接參考的結(jié)構(gòu)和可復(fù)現(xiàn)的代碼片段照著改就能用。2. 可行性研究分析C# 與 SQL Server 的選型、經(jīng)濟(jì)賬和運(yùn)行條件2.1 技術(shù)可行性C# SQL Server 為什么是課設(shè)的安全牌技術(shù)可行性要回答一個(gè)問題現(xiàn)有條件和技術(shù)儲(chǔ)備到底能不能把系統(tǒng)做出來。原方案定的是 Visual C# 做前臺(tái)SQL Server 做后臺(tái)數(shù)據(jù)庫Windows 7 為操作平臺(tái)。這個(gè)組合對(duì)課程設(shè)計(jì)來說非常穩(wěn)妥C# 作為面向?qū)ο蟮拈_發(fā)框架提供了完善的指令控制語句、類與對(duì)象的支持以及豐富的數(shù)據(jù)類型代碼模塊化程度高后續(xù)要擴(kuò)展房型管理或者增加統(tǒng)計(jì)報(bào)表不需要推翻重寫SQL Server 則承擔(dān)了所有客房靜態(tài)數(shù)據(jù)、客戶動(dòng)態(tài)數(shù)據(jù)和結(jié)算數(shù)據(jù)的存儲(chǔ)事務(wù)處理和權(quán)限控制都比輕量級(jí)數(shù)據(jù)庫可靠。這里有一個(gè)容易糾結(jié)的選型點(diǎn)要不要上網(wǎng)絡(luò)版。原方案明確把系統(tǒng)定位成單機(jī)版本原因很實(shí)際——當(dāng)時(shí)調(diào)研的某賓館前臺(tái)服務(wù)人員以青年員工為主能熟練操作電腦賓館也配備了性能足夠的機(jī)器但他們暫時(shí)不需要多用戶共享數(shù)據(jù)先把單機(jī)版做扎實(shí)比盲目做 C/S 網(wǎng)絡(luò)版更現(xiàn)實(shí)。技術(shù)上真正要驗(yàn)證的只有三件事能不能穩(wěn)定連庫、能不能在窗體里完成增刪改查、能不能在 1 秒內(nèi)返回查詢結(jié)果這三件事 C# 加 SQL Server 都能滿足。2.2 經(jīng)濟(jì)可行性投入 4 萬元、三年回本的數(shù)字依據(jù)經(jīng)濟(jì)可行性不是讓學(xué)生真的去投標(biāo)但報(bào)告里必須把賬算完整因?yàn)榇疝q時(shí)老師很愛問“為什么值得做”。原方案給了一套可以直接用的成本結(jié)構(gòu)表。成本項(xiàng)金額萬元說明人力成本2.87 人4000 元/人/月網(wǎng)線與輔助耗材0.2布線、接口調(diào)試等計(jì)算機(jī)設(shè)備1.0PC 機(jī) 2 臺(tái)系統(tǒng)開發(fā)總投資4.0一次性投入新系統(tǒng)運(yùn)行費(fèi)用為人力和物資 0.4 萬元/年維護(hù) 0.2 萬元/年合計(jì) 0.6 萬元/年原有手工管理方式的實(shí)際運(yùn)行費(fèi)用約 2.4 萬元/年。按每年節(jié)省約 2 萬元測(cè)算折現(xiàn)后三年累計(jì)現(xiàn)值為 54470 元投資回收期 3 年折現(xiàn)后凈收入約 12470 元。這里面的數(shù)字邏輯是投資雖然要 4 萬但每年能省下 2 萬左右系統(tǒng)用滿三年就是凈賺這個(gè)賬在答辯現(xiàn)場(chǎng)能直接說清楚。經(jīng)濟(jì)收益還要落到業(yè)務(wù)價(jià)值上原方案列了五條電腦收銀打印賬單快速準(zhǔn)確減少賓客等待時(shí)間同時(shí)能杜絕收銀過程中的舞弊房態(tài)管理更高效能提高客房入住率增加營業(yè)收入管理者能隨時(shí)了解經(jīng)營情況為制定經(jīng)營方針提供決策依據(jù)員工從煩瑣的記賬中解放出來把精力放到服務(wù)質(zhì)量上歷史資料長(zhǎng)期保存在數(shù)據(jù)庫里查詢和統(tǒng)計(jì)都比翻紙質(zhì)臺(tái)賬方便得多。這五條既是經(jīng)濟(jì)可行性的論據(jù)也是后面做需求分析的功能來源。2.3 運(yùn)行可行性使用者、硬件條件與故障處理運(yùn)行可行性考慮的是系統(tǒng)交付后“有沒有人用、機(jī)器帶不帶的動(dòng)、壞了怎么辦”。中小型賓館管理系統(tǒng)的資源消耗很小賓館現(xiàn)有計(jì)算機(jī)無論硬件還是軟件都能滿足運(yùn)行條件使用者以一線前臺(tái)服務(wù)人員為主他們對(duì)計(jì)算機(jī)操作并不陌生只需要培訓(xùn)登錄、入住登記、退房結(jié)算這幾個(gè)高頻操作即可上手。故障處理這塊容易被忽略但報(bào)告里專門寫了病毒及黑客破壞的風(fēng)險(xiǎn)通過配備殺毒軟件和防火墻、系統(tǒng)不連接外網(wǎng)來規(guī)避。這個(gè)思路很符合單機(jī)版定位——業(yè)務(wù)數(shù)據(jù)不暴露在公網(wǎng)運(yùn)行環(huán)境相對(duì)可控維護(hù)成本也低。運(yùn)行可行性部分不用寫太長(zhǎng)結(jié)論要明確系統(tǒng)使用門檻低、硬件軟件條件均滿足可以進(jìn)入開發(fā)階段。3. 軟件需求分析三類角色、十條功能與數(shù)據(jù)字典的落地方法3.1 功能需求十條功能怎么覆蓋入住到離店的完整閉環(huán)需求分析階段的重點(diǎn)是把“賓館要干什么”翻譯成系統(tǒng)要提供的功能清單。原方案先列了七個(gè)基本功能需求用戶登錄、按房型及價(jià)格查詢可用房間、登記客戶入住信息、客戶離店結(jié)算、按時(shí)間段與價(jià)格范圍及房型查詢統(tǒng)計(jì)客房使用情況、客房信息維護(hù)、用戶信息維護(hù)。這是系統(tǒng)的骨架。在此基礎(chǔ)上擴(kuò)展成十條功能才算是完整的業(yè)務(wù)閉環(huán)客戶信息管理、客房信息管理、用戶信息錄入、統(tǒng)計(jì)功能、瀏覽功能、查詢功能、修改功能、刪除功能、結(jié)賬功能、押金管理功能。其中押金管理最有業(yè)務(wù)特色系統(tǒng)每天 12:00 自動(dòng)扣除入住用戶一天客房費(fèi)18:00 自動(dòng)扣除半天客房費(fèi)服務(wù)員用戶可以查看余額并及時(shí)提醒客戶。這條規(guī)則直接來自賓館實(shí)際的日租和半日租結(jié)算方式放在需求文檔里會(huì)讓老師覺得你確實(shí)調(diào)研過業(yè)務(wù)不是憑空設(shè)計(jì)。3.2 用戶角色與權(quán)限劃分服務(wù)員、管理員、系統(tǒng)用戶各能做什么權(quán)限設(shè)計(jì)是這套系統(tǒng)最值得講清楚的部分。原方案把用戶分成三個(gè)角色每個(gè)角色的操作范圍完全不同。服務(wù)員用戶客房查詢、客戶入住登記、客戶換房、消費(fèi)結(jié)算、押金管理、添加消費(fèi)、修改密碼、退出系統(tǒng)。這個(gè)角色覆蓋了前臺(tái)日常最頻繁的操作權(quán)限集中在“執(zhí)行”層面。管理員用戶客房管理、消費(fèi)信息管理、財(cái)務(wù)管理、客戶查詢、密碼修改、退出系統(tǒng)。管理員多出了對(duì)客房?jī)r(jià)格、客房類型、消費(fèi)記錄的維護(hù)權(quán)限還能按時(shí)間段或按房間類型統(tǒng)計(jì)收入支出但統(tǒng)計(jì)結(jié)果只能查看不可修改。系統(tǒng)用戶用戶信息管理、密碼修改、退出系統(tǒng)。系統(tǒng)用戶負(fù)責(zé)維護(hù)整個(gè)系統(tǒng)的賬號(hào)體系能添加、刪除員工賬號(hào)并分配權(quán)限員工也可以自行修改密碼。角色劃分的邏輯是服務(wù)員做業(yè)務(wù)、管理員管業(yè)務(wù)數(shù)據(jù)、系統(tǒng)用戶管賬號(hào)權(quán)限。原方案里特別強(qiáng)調(diào)“非用戶不開放且需密碼不可直接進(jìn)入進(jìn)行操作”后臺(tái)管理員和系統(tǒng)用戶的信息量大數(shù)據(jù)安全性和保密性要求最高。答辯演示時(shí)建議把三個(gè)角色各走一遍登錄等于給老師現(xiàn)場(chǎng)展示權(quán)限控制是真實(shí)生效的。3.3 數(shù)據(jù)流圖與數(shù)據(jù)字典需求怎么變成可審查的文檔數(shù)據(jù)流圖是需求分析階段最能體現(xiàn)軟件工程功底的產(chǎn)物。原方案畫了四張數(shù)據(jù)流圖客房流程圖、住宿流程圖、員工流程圖、消費(fèi)品流程圖。它們的共同結(jié)構(gòu)是“數(shù)據(jù)的錄入 → 數(shù)據(jù)庫 → 查詢/修改”但來源角色不同??头繑?shù)據(jù)由管理員錄入和修改住宿數(shù)據(jù)由前臺(tái)服務(wù)員錄入員工數(shù)據(jù)由系統(tǒng)用戶管理消費(fèi)品數(shù)據(jù)在消費(fèi)發(fā)生時(shí)生成。數(shù)據(jù)字典是評(píng)審老師最喜歡抽查的部分因?yàn)榇a可以臨時(shí)改數(shù)據(jù)字典對(duì)不上就說明需求分析是抄的。原方案定義得非常完整我整理成下面這張表。數(shù)據(jù)項(xiàng)關(guān)鍵字段用途登記信息客戶編號(hào)、客房號(hào)、登記時(shí)間、預(yù)住天數(shù)、押金、在店?duì)顟B(tài)、折扣率記錄客戶入住核心數(shù)據(jù)客房信息客房號(hào)、客房類型、客房狀態(tài)、電話號(hào)碼、所在樓層房態(tài)與房間屬性客房類型信息客房類型、客房面積、租金、房間配置房型與價(jià)格管理換房信息換房時(shí)間、客戶編號(hào)、舊房號(hào)、新房號(hào)、記錄人員號(hào)換房操作留痕消費(fèi)信息消費(fèi)時(shí)間、客戶編號(hào)、客房號(hào)、物品單價(jià)、數(shù)量、消費(fèi)金額客戶在店期間消費(fèi)明細(xì)結(jié)算信息結(jié)算時(shí)間、客戶編號(hào)、客房號(hào)、住房費(fèi)、其他消費(fèi)、總消費(fèi)額離店結(jié)算賬單用戶信息用戶編號(hào)、用戶姓名、用戶身份、用戶帳號(hào)、用戶密碼系統(tǒng)賬號(hào)與權(quán)限數(shù)據(jù)采集方式也很簡(jiǎn)單直接客人敘述前臺(tái)通過鍵盤鼠標(biāo)錄入。這意味著界面設(shè)計(jì)要盡量減少輸入次數(shù)多提供下拉選擇和快捷按鈕這條需求直接影響了用戶界面設(shè)計(jì)標(biāo)準(zhǔn)。3.4 性能與數(shù)據(jù)精度需求查詢小于 1 秒、金額精確到元性能需求寫進(jìn)需求文檔才有驗(yàn)收依據(jù)。原方案定的指標(biāo)是查詢時(shí)間小于 1 秒更新數(shù)據(jù)文件時(shí)間小于 100 毫秒。這個(gè)指標(biāo)對(duì)單機(jī)版 C/S 系統(tǒng)沒有任何壓力但要寫出來因?yàn)樗呛竺孀鰷y(cè)試用例時(shí)判斷“是否達(dá)標(biāo)”的準(zhǔn)繩。數(shù)據(jù)精度需求同樣要固化下來實(shí)際宿費(fèi)按兩位小數(shù)計(jì)算結(jié)果保留整數(shù)精確到人民幣元預(yù)收押金按兩位小數(shù)計(jì)算結(jié)果保留整數(shù)房?jī)r(jià)金額同樣精確到元。這條需求典型是業(yè)務(wù)驅(qū)動(dòng)的——賬單一分錢對(duì)不上前臺(tái)和財(cái)務(wù)就會(huì)吵起來。最后是可維護(hù)性要求參數(shù)及文本內(nèi)容全部放在數(shù)據(jù)庫中改價(jià)格、改房型配置不需要改代碼這也是為什么數(shù)據(jù)庫設(shè)計(jì)部分必須單獨(dú)成章。4. 總體設(shè)計(jì)與詳細(xì)設(shè)計(jì)登錄流程、押金規(guī)則與換房結(jié)算的實(shí)現(xiàn)4.1 體系結(jié)構(gòu)從登錄窗體到數(shù)據(jù)庫的三層職責(zé)劃分總體設(shè)計(jì)階段要交代清楚系統(tǒng)長(zhǎng)什么樣。中小型賓館管理系統(tǒng)按用戶角色拆成三大模塊系統(tǒng)用戶模塊、管理員用戶模塊、服務(wù)員用戶模塊按管理對(duì)象又分為客戶管理、客房管理、用戶管理。程序的主流程是啟動(dòng)系統(tǒng)進(jìn)入登錄界面輸入用戶名和密碼后由數(shù)據(jù)庫校驗(yàn)身份校驗(yàn)通過后根據(jù)用戶身份跳轉(zhuǎn)到對(duì)應(yīng)角色的操作界面執(zhí)行各類業(yè)務(wù)操作后退出系統(tǒng)。體系結(jié)構(gòu)可以理解為三層。界面層是 C# WinForms 窗體包括登錄界面、各角色主界面、系統(tǒng)用戶編輯界面、修改密碼界面業(yè)務(wù)處理層承接登錄校驗(yàn)、房態(tài)查詢、入住登記、換房、結(jié)算、押金扣費(fèi)等邏輯數(shù)據(jù)層是 SQL Server 數(shù)據(jù)庫存放客房、客戶、消費(fèi)、結(jié)算、用戶等全部數(shù)據(jù)。三層各自獨(dú)立后面要加需求優(yōu)先改業(yè)務(wù)層而不動(dòng)界面和數(shù)據(jù)庫結(jié)構(gòu)。4.2 系統(tǒng)登錄模塊設(shè)計(jì)與代碼實(shí)現(xiàn)登錄模塊是系統(tǒng)的入口原方案給出了非常標(biāo)準(zhǔn)的處理流程先校驗(yàn)字符有效性檢查用戶名和密碼文本框是否為空再校驗(yàn)用戶名是否存在、密碼是否正確然后從數(shù)據(jù)庫提取用戶權(quán)限根據(jù)權(quán)限調(diào)用對(duì)應(yīng)頁面服務(wù)員進(jìn)入服務(wù)員界面管理員進(jìn)入管理員界面系統(tǒng)用戶進(jìn)入系統(tǒng)用戶界面取消登錄則退出整個(gè)程序。賬號(hào)密碼不區(qū)分大小寫長(zhǎng)度都為 20 位修改密碼前必須先輸入原密碼。核心的登錄查詢代碼可以用 C# 寫成下面這樣。// 登錄按鈕點(diǎn)擊事件 // connectionString 指向本機(jī) SQL Server 的 HotelDB 數(shù)據(jù)庫 string sql SELECT 用戶身份 FROM 用戶信息 WHERE 用戶帳號(hào)acc AND 用戶密碼pwd; using (SqlConnection conn new SqlConnection(connectionString)) { conn.Open(); SqlCommand cmd new SqlCommand(sql, conn); // 參數(shù)化查詢避免拼字符串帶來的注入風(fēng)險(xiǎn) cmd.Parameters.AddWithValue(acc, txtUser.Text.Trim()); cmd.Parameters.AddWithValue(pwd, txtPwd.Text.Trim()); object result cmd.ExecuteScalar(); if (result null) { MessageBox.Show(用戶名或密碼錯(cuò)誤); return; } // 根據(jù)用戶身份跳轉(zhuǎn)對(duì)應(yīng)窗體 string role result.ToString(); switch (role) { case 服務(wù)員: new FrmWaiter().Show(); break; case 管理員: new FrmAdmin().Show(); break; case 系統(tǒng)用戶: new FrmSysUser().Show(); break; } }這段代碼有三個(gè)關(guān)鍵點(diǎn)。第一用 Parameters.AddWithValue 做參數(shù)化查詢而不是直接拼接字符串這是安全性底線第二用 ExecuteScalar 只取第一行第一列登錄驗(yàn)證不需要查出整行數(shù)據(jù)第三用戶身份字段直接決定跳轉(zhuǎn)目標(biāo)權(quán)限控制從入口就開始生效而不是進(jìn)入界面后再判斷。4.3 押金自動(dòng)扣費(fèi)12:00 與 18:00 兩個(gè)時(shí)間點(diǎn)的實(shí)現(xiàn)方案押金管理是這套系統(tǒng)里最有業(yè)務(wù)特色的模塊。規(guī)則是每天 12:00 自動(dòng)扣除入住用戶一天客房費(fèi)18:00 自動(dòng)扣除半天客房費(fèi)服務(wù)員用戶可以查看押金余額并及時(shí)提醒客戶。這段邏輯如果只在交班時(shí)由人工操作很容易漏扣或者記錯(cuò)時(shí)間所以設(shè)計(jì)成定時(shí)觸發(fā)。單機(jī)版系統(tǒng)里最直接的做法是用 WinForms 的 Timer 控件設(shè)置每秒或每分鐘檢查一次當(dāng)前時(shí)間。// 定時(shí)器間隔設(shè)為 60000 毫秒1分鐘 private void timerDeduct_Tick(object sender, EventArgs e) { DateTime now DateTime.Now; // flag12 與 flag18 防止同一天內(nèi)重復(fù)扣費(fèi) if (now.Hour 12 now.Minute 0 !flag12) { // 扣除在店客戶一天房費(fèi) DeductRoomFee(1); flag12 true; } if (now.Hour 18 now.Minute 0 !flag18) { DeductRoomFee(0.5); flag18 true; } // 跨天重置兩個(gè)標(biāo)記保證第二天還能觸發(fā) if (now.Hour 0 now.Minute 0) { flag12 false; flag18 false; } }DeductRoomFee 內(nèi)部執(zhí)行一條更新語句按客房租金乘以扣費(fèi)天數(shù)更新在店客戶的押金余額Update 條件里必須帶上“在店?duì)顟B(tài) 在店”否則會(huì)把已經(jīng)退房的客戶也扣一遍。設(shè)計(jì)說明要強(qiáng)調(diào)兩點(diǎn)flag 標(biāo)記避免同一時(shí)間點(diǎn)重復(fù)扣費(fèi)跨天重置標(biāo)記保證定時(shí)邏輯可持續(xù)運(yùn)行。更穩(wěn)妥的做法是把扣費(fèi)寫成 SQL Server 存儲(chǔ)過程由程序定時(shí)調(diào)用這樣扣費(fèi)規(guī)則和扣費(fèi)記錄都能在數(shù)據(jù)庫端留痕。4.4 客房查詢與換房流程SQL 查詢與事務(wù)要點(diǎn)客房查詢要支持按客房號(hào)、客房類型、客房?jī)r(jià)格、客房狀態(tài)四個(gè)維度組合查詢核心是一條帶條件的 SQL。-- 按房型、價(jià)格范圍、客房狀態(tài)查詢可用房間 -- type、minPrice、maxPrice 從界面下拉框和輸入框取值 SELECT 客房號(hào), 客房類型, 租金, 客房狀態(tài) FROM 客房信息 WHERE 客房狀態(tài) 空房 AND 客房類型 type AND 租金 BETWEEN minPrice AND maxPrice ORDER BY 租金;BETWEEN 寫法比“租金 minPrice AND 租金 maxPrice”更簡(jiǎn)潔而且語義清晰價(jià)格區(qū)間包含邊界值。房態(tài)字段是關(guān)鍵只有狀態(tài)為“空房”的房間才允許辦理入住。換房流程比查詢復(fù)雜得多它涉及登記信息、客房狀態(tài)、換房記錄三處數(shù)據(jù)變更。正確順序是把登記信息中的客房號(hào)改為新房號(hào)將舊房狀態(tài)置為“空房”新房狀態(tài)置為“入住中”在換房信息表里寫入換房時(shí)間、客戶編號(hào)、舊房號(hào)、新房號(hào)、記錄人員號(hào)。這三步必須放在同一個(gè)數(shù)據(jù)庫事務(wù)里提交否則會(huì)出現(xiàn)“登記信息改了但房態(tài)沒改”或者“房態(tài)改了但換房記錄沒寫”的中間狀態(tài)前臺(tái)查到的房態(tài)就是錯(cuò)的。5. 數(shù)據(jù)庫設(shè)計(jì)與常見問題排查六張核心表的關(guān)系與五個(gè)翻車點(diǎn)5.1 實(shí)體屬性與 E-R 關(guān)系六類實(shí)體怎么組織數(shù)據(jù)庫設(shè)計(jì)是這套系統(tǒng)的數(shù)據(jù)底座。原方案先定義實(shí)體及其屬性再畫 E-R 圖最后落成表結(jié)構(gòu)和表間關(guān)系。核心實(shí)體有六個(gè)客戶登記信息、客房、客房類型、換房記錄、消費(fèi)記錄、結(jié)算記錄再加上系統(tǒng)用戶一共七類。實(shí)體關(guān)系的主線非常清晰??蛻舻怯浶畔⑹侵行膶?shí)體它關(guān)聯(lián)客房一個(gè)客戶入住一間房客房號(hào)是外鍵關(guān)聯(lián)消費(fèi)記錄客戶在店期間所有消費(fèi)按客戶編號(hào)歸集關(guān)聯(lián)結(jié)算記錄離店時(shí)生成一張賬單。換房記錄比較特殊它同時(shí)關(guān)聯(lián)舊房號(hào)和新房號(hào)用來保留客戶換房的歷史痕跡。用戶信息表則通過“登記人號(hào)”“服務(wù)員編號(hào)”“結(jié)算人員號(hào)”分別與登記、消費(fèi)、結(jié)算關(guān)系掛上方便日后追溯“這筆業(yè)務(wù)是誰經(jīng)手的”。E-R 圖答辯時(shí)不需要背但要能指著圖說出“客戶編號(hào)是貫穿表間關(guān)系的主線索”。5.2 核心表結(jié)構(gòu)與表間關(guān)系登記、消費(fèi)、結(jié)算怎么關(guān)聯(lián)表結(jié)構(gòu)直接決定后面寫查詢語句的難易程度。下面是各表的主鍵和關(guān)鍵外鍵關(guān)系。表名主鍵關(guān)鍵外鍵/關(guān)聯(lián)字段作用登記信息客戶編號(hào)客房號(hào)、登記人號(hào)在店客戶核心檔案客房信息客房號(hào)無房態(tài)與位置客房類型信息客房類型無房型價(jià)格配置換房信息換房時(shí)間客戶編號(hào)客戶編號(hào)、舊房號(hào)、新房號(hào)換房留痕消費(fèi)信息消費(fèi)時(shí)間客戶編號(hào)客戶編號(hào)、客房號(hào)、服務(wù)員編號(hào)在店消費(fèi)明細(xì)結(jié)算信息結(jié)算時(shí)間客戶編號(hào)客戶編號(hào)、客房號(hào)、結(jié)算人員號(hào)離店賬單用戶信息用戶編號(hào)無賬號(hào)與權(quán)限最常用的關(guān)聯(lián)查詢是按客戶編號(hào)匯總消費(fèi)例如前臺(tái)要給客人看“從入住到現(xiàn)在一共消費(fèi)了什么”。-- 按客戶編號(hào)查詢客戶全部消費(fèi)明細(xì) SELECT r.客戶姓名, c.消費(fèi)時(shí)間, c.消費(fèi)物品, c.物品數(shù)量, c.消費(fèi)金額 FROM 消費(fèi)信息 c INNER JOIN 登記信息 r ON c.客戶編號(hào) r.客戶編號(hào) WHERE c.客戶編號(hào) custId ORDER BY c.消費(fèi)時(shí)間;這里用 INNER JOIN 而不是子查詢是因?yàn)榧纫M(fèi)明細(xì)又要客戶姓名兩條數(shù)據(jù)分屬兩張表連接查詢一次就能取齊??蛻艟幪?hào)作為關(guān)聯(lián)字段的好處是即使客戶中間換了房所有消費(fèi)仍然能按人歸集不會(huì)因?yàn)榉刻?hào)變了就查不到。5.3 常見問題排查五個(gè)最容易翻車的點(diǎn)第一個(gè)翻車點(diǎn)是押金扣費(fèi)重復(fù)扣或漏扣。現(xiàn)象客戶明明下午 3 點(diǎn)入住12:00 的自動(dòng)扣費(fèi)卻把當(dāng)天房費(fèi)也扣了或者系統(tǒng)時(shí)間跨過 12 點(diǎn)后扣費(fèi)執(zhí)行了兩次。原因Timer 觸發(fā)邏輯沒有判斷客戶“在店?duì)顟B(tài)”且沒做防重復(fù)標(biāo)記。解決Update 語句強(qiáng)制加上在店?duì)顟B(tài) 在店 條件并用布爾標(biāo)記保證同一個(gè)時(shí)間點(diǎn)只執(zhí)行一次跨天重置標(biāo)記。第二個(gè)翻車點(diǎn)是結(jié)算金額與手工賬差幾毛錢?,F(xiàn)象房費(fèi)加消費(fèi)算出來是 198.56 元前臺(tái)手工按 198 元收系統(tǒng)又顯示 199 元。原因C# 端 Math.Round 默認(rèn)的舍入模式和 SQL Server 的 ROUND 函數(shù)行為不一致。解決在需求文檔里寫死“金額兩位小數(shù)計(jì)算結(jié)果保留整數(shù)精確到元”并且只在同一層做舍入前臺(tái)界面和數(shù)據(jù)庫存儲(chǔ)過程不要各舍一次。第三個(gè)翻車點(diǎn)是換房后消費(fèi)記錄掛在舊房號(hào)上?,F(xiàn)象客人換了房又買了飲料結(jié)算時(shí)按新房號(hào)查消費(fèi)少了一筆。原因消費(fèi)信息表存的是客房號(hào)換房只改了登記信息后續(xù)消費(fèi)繼續(xù)按舊房號(hào)錄入。解決換房操作在同一事務(wù)里完成登記房號(hào)更新和房態(tài)切換并向操作人員提示后續(xù)消費(fèi)統(tǒng)一用客戶編號(hào)錄入統(tǒng)計(jì)消費(fèi)時(shí)以客戶編號(hào)為準(zhǔn)不依賴房號(hào)。第四個(gè)翻車點(diǎn)是密碼明文存儲(chǔ)或賬號(hào)大小寫對(duì)不上。現(xiàn)象打開數(shù)據(jù)庫就能直接看到所有用戶的密碼或者用戶用大寫字母登錄失敗。原因用戶信息表密碼字段沒做任何處理且 SQL Server 默認(rèn)排序規(guī)則可能區(qū)分大小寫。解決登錄比對(duì)時(shí)統(tǒng)一轉(zhuǎn)大寫或小寫存儲(chǔ)層至少要避免明文課設(shè)可以不引入復(fù)雜加密但要對(duì)密碼做簡(jiǎn)單變換處理報(bào)告里寫明理由。第五個(gè)翻車點(diǎn)是數(shù)據(jù)字典與表結(jié)構(gòu)對(duì)不上?,F(xiàn)象數(shù)據(jù)字典里寫“在店?duì)顟B(tài)”數(shù)據(jù)庫字段名卻是“入住狀態(tài)”答辯演示時(shí)老師對(duì)照文檔一問就露餡。原因先寫完文檔再寫代碼中途調(diào)整了字段沒有回填。解決養(yǎng)成習(xí)慣每改一次表結(jié)構(gòu)就同步更新數(shù)據(jù)字典和 E-R 圖答辯前逐字段核對(duì)一遍數(shù)據(jù)庫表。維護(hù)文檔實(shí)際上是給后期的自己留后悔藥這比任何技巧都重要。6. 系統(tǒng)測(cè)試與答辯驗(yàn)收測(cè)試用例、演示腳本與答辯話術(shù)6.1 測(cè)試用例與驗(yàn)收標(biāo)準(zhǔn)從登錄到押金扣費(fèi)逐項(xiàng)過測(cè)試階段不能只寫“系統(tǒng)運(yùn)行正?!币垂δ茳c(diǎn)設(shè)計(jì)可執(zhí)行的測(cè)試用例。下面是推薦覆蓋的六個(gè)核心用例。用例名稱前置條件操作步驟預(yù)期結(jié)果正常登錄數(shù)據(jù)庫存在服務(wù)員工號(hào)輸入正確工號(hào)和密碼進(jìn)入服務(wù)員操作界面錯(cuò)誤密碼鎖定無連續(xù)三次輸入錯(cuò)誤密碼提示錯(cuò)誤不進(jìn)入系統(tǒng)按價(jià)格區(qū)間查詢存在空房輸入價(jià)格范圍并選擇房型1 秒內(nèi)返回可用房間列表客戶入住登記存在空房填寫客戶信息和預(yù)住天數(shù)房態(tài)變?yōu)槿胱≈猩裳航鹩涗浹航鹱詣?dòng)扣費(fèi)存在在店客戶調(diào)整系統(tǒng)時(shí)間至 12:00押金自動(dòng)扣減一天房費(fèi)只扣一次離店結(jié)算在店客戶有消費(fèi)記錄點(diǎn)擊結(jié)算并打印賬單賬單等于房費(fèi)加消費(fèi)減已扣押金驗(yàn)收標(biāo)準(zhǔn)直接引用需求分析階段的性能指標(biāo)查詢時(shí)間小于 1 秒更新數(shù)據(jù)文件小于 100 毫秒金額精確到元。每項(xiàng)測(cè)試通過后在測(cè)試記錄里勾選結(jié)果形成一張完整的測(cè)試表格這份記錄本身就是答辯的加分材料。6.2 答辯演示腳本與老師追問的回答思路演示順序建議固定成一條完整的業(yè)務(wù)鏈先用系統(tǒng)用戶登錄新建服務(wù)員賬號(hào)再用管理員配置房型和價(jià)格然后用服務(wù)員做入住登記、添加消費(fèi)、觸發(fā)換房調(diào)整系統(tǒng)時(shí)間到 12:00 演示押金自動(dòng)扣費(fèi)最后做離店結(jié)算用統(tǒng)計(jì)功能展示收入?yún)R總。這條鏈走完等于把需求分析里的每一條功能都現(xiàn)場(chǎng)驗(yàn)證了一遍。老師最常追問的三個(gè)問題需要提前準(zhǔn)備答案。為什么用單機(jī)版調(diào)研時(shí)賓館暫時(shí)不需要多用戶共享數(shù)據(jù)單機(jī)版投入小、交付快后續(xù)需要聯(lián)網(wǎng)可以平滑擴(kuò)展。為什么押金設(shè) 12 點(diǎn)和 18 點(diǎn)兩個(gè)扣費(fèi)時(shí)間這是賓館實(shí)際執(zhí)行的日租金和半日租金規(guī)則系統(tǒng)只是把人工規(guī)則自動(dòng)化。表間為什么用客戶編號(hào)關(guān)聯(lián)客戶可能換房按房號(hào)關(guān)聯(lián)會(huì)導(dǎo)致消費(fèi)記錄串房按客戶編號(hào)歸集才能保證賬單準(zhǔn)確。我后來做其他系統(tǒng)也保持一個(gè)習(xí)慣每改一次表結(jié)構(gòu)先回填數(shù)據(jù)字典再寫下一段代碼默認(rèn)這能省掉答辯前所有熬夜。那次課程設(shè)計(jì)之后我就明白軟件工程報(bào)告不是寫給老師看的文檔是給未來的自己留的后路。這套方案從需求到驗(yàn)收的每一步都能落地希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取