前言
這是大學時候上設計模式這門課寫的程式,當時課程任務是要求結合五個設計模式寫一個系統,最近偶然翻到,把系統分享一下。
成品預覽
主介面
功能介紹
訂單管理系統,實現了對訂單的增刪改查。且實現了將訂單內容寫入檔案,每次增刪改查都會做儲存,下次重啟程式時會自動載入之前已存入的訂單,簡單採用txt存檔案到本地。
功能描述:
(1) 增加訂單功能:能對不同商品組合實現實時計算價格,並且根據使用者的身份產生vip使用者價格和普通使用者價格,並在訂單新增到已有的訂單列表中。並且內建了商品選單,點選商品選單按鈕可以顯示詳細的商品選單。 如果未確認選擇先提交訂單,會提示“訂單為空,無法提交”。 如果未確認選擇而單擊撤回選擇,會提示“訂單為空無法撤回”。 如果未選擇客戶型別便進行確認選擇,會提示“未選擇客戶型別”。
(2) 查詢訂單功能:輸入訂單號實現對訂單查詢操作。能實現對訂單號格式的校驗,只能是數字格式,並且非空,若格式錯誤會彈窗提示,當訂單不存在時候也會彈出錯誤提示。
(3) 刪除訂單功能:輸入要刪除的訂單號,完成對訂單的刪除。並且可以撤回刪除操作。當想恢復上一次刪除的內容時,單擊撤回刪除按鈕即可實現。能實現對訂單號格式的校驗,只能是數字格式,並且非空,若格式錯誤會彈窗提示,當訂單不存在時候也會彈出錯誤提示
(4) 修改功能:使用了JTable,直接雙擊表格文字框即可完成修改和儲存。
使用的設計模式
裝飾者模式
在增加新訂單中,對訂單的計價和描述使用了裝飾者模式。原先沒有裝飾者模式,則需要對每種組合都定義一個類,在類中設定其相關的價格和描述屬性,將會使得類的數量龐大。應用該模式後,可以大大減少類的數量。 使用裝飾者模式。有咖啡和茶兩種飲品,都繼承自一個抽象類Drink。配料有糖分,牛奶,豆漿三種配料,將配料作為decorator裝飾飲品,繼承自decorator,同時decorator又繼承自Drink類。使用裝飾模式,可以動態的給物件新增額外的功能,即包裝原有的類。這樣子,一個飲品新增多個配料,實現對飲品物件的多次包裝,每次包裝都後都能儲存物件原有的功能屬性。這種情況下,無需增加不同組合的類,即可完成對每個組合的商品描述和計價。
UML圖:
組合模式
在增加新訂單功能中,有顯示商品選單選項。對商品選單的展示則應用了組合模式。如果選單沒有使用組合模式,將不能很好的實現管理操作,如對選單的一級目錄,二級目錄,三級目錄……的新增,刪除,遍歷。 應用組合模式,在該系統中,一級目錄對應飲品(Drinks類),二級目錄對應咖啡,茶,配料(DrinkTypes),三級目錄(SpecificTypes)是二級目錄各飲品的詳細種類。將選單的一級目錄,二級目錄,三級目錄看成是組織結構,將他們的關係看成樹形結構,這樣子利於實現管理操作。能透過add的操作,向現有的選單中新增新的目錄選項,或者透過remove操作,刪除對應目錄下不需要的內容。
UML圖:
備忘錄模式
撤銷刪除功能,應用到了備忘錄模式。沒有使用備忘錄模式前,備份刪除前的狀態需要new一個新的物件,並把需要備份的資料存到物件中,這暴露了物件內部的細節,如果需要備份的物件很多,這將不利於管理,開銷也會變大。 備忘錄模式能在不破壞封裝性前提下,捕獲物件的狀態,在物件之外儲存這個狀態,並可用於恢復儲存的狀態。在訂單管理下,Memento為訂單orderList的備份類,careTaker用於維護以Memento為元素的List。當有訂單被刪除時,刪除前的orderlist的狀態就會被儲存到careTaker的MementoList中。這時,選擇撤銷的話careTaker就會從List中選取上次備份的內容,完成撤回操作。
UML圖:
代理模式
對vip使用者和普通使用者的區別計價,用到了代理模式。使用代理模式,對訂單的總價格RealPrice類,提供一種代理以控制對這個物件的訪問。RealPrice類(被代理類)和Proxy類(代理類)都實現同一個介面ProductPrice,在Proxy類實現實際業務邏輯,在該代理類的控制下,普通客戶訪問將得到原價價格,vip客戶訪問將得到八八折的價格。代理模式在一定程度上降低了耦合度,且如果對代理類做修改,則無需對被代理類進行改動,使得系統具有良好的靈活性和可擴充套件性,比如想新增一種客戶型別,則直接更改代理類即可。
UML圖:
單例模式
在圖形介面中,對檢視所有訂單介面(GuiMain類)和增加新訂單介面(GuiAdd類)會來回切換,若不使用單例模式,每次切換都要new一個新的介面物件,頻繁的進行建立物件,耗費資源。 而使用單例模式,可以保證該類中只存在一個這樣的物件,確保只有單個物件被建立,節省了系統資源,可以提高系統的效能。在單例模式下,檢視所有訂單介面(GuiMain類)和新增新訂單介面(GuiAdd類)都是透過使用getInstance函式建立唯一的例項,解決了耗費資源的情況。
UML圖:
使用
開啟IDEA,執行main包中的MainTest啟動程式
進入程式主介面,載入已儲存的訂單
增加新訂單:
返回主介面,在最後一行能找到新增的訂單
檢視商品選單
未選擇客戶型別時候:
未確認選擇情況下撤回選擇
未確認選擇情況下提交訂單
存在未提交訂單情況下點選確認選擇:
查詢訂單:
訂單號不存在,或者訂單格式有問題:
刪除訂單:
訂單號不存在,或者訂單格式有問題:
撤回刪除: 執行撤回前:
執行撤回後:
不存在刪除操作時:
修改訂單:單擊修改訂單顯示
直接在表格上即可進行修改,修改將自動儲存
遇到的問題
在程式除錯時,遇到一個大問題,無法讓顯示訂單的表格實時更新內容 。使用JAVA圖形介面,想實現對所有訂單在同一個介面顯示,並且要其支援修改和儲存。這種情況下用JTable可以來實現所有訂單的顯示。但用了JTable後,卻發現訂單的新增,刪除,表格都不會重新整理新資料,在此嘗試了好多種辦法解決。在經過長時間的鑽研下,發現藉助DefaultTableModel物件可以實現,之後再使用Vector陣列儲存表格每行每列的資料,呼叫setDataVector方法為DefaultTableModel物件存值。每次新增,刪除訂單都重複上述操作,使得表格內的內容能被實時更新。
合理運用設計模式,無疑是可以簡化類的數量,簡化不必要的程式碼,使系統程式碼可讀性更高,更簡潔,且可以最佳化系統的效能。如對單例模式的應用,能使物件不會被重複new出來,節約系統資源。再如裝飾者模式可以大幅度減少類的數量,使用decorator對特定物件新增功能,即可實現不同組合。合理運用設計模式,是可以減少類之間的耦合性,並使得系統的擴充套件性得到提高。
連結
scottyzh/MilkTea-Order-System: 奶茶訂單生成系統,使用多種設計模式 (github.com)