962 C++ 程式作業四:             
     簡易錄影帶/碟片租售店管理程式 (II)
(線上繳交截止時間 97/06/09(一) 24:00)

在上一次的作業中大家已經寫了一個錄影帶/碟片租售店管理程式的雛型, 當然比較不幸的是有同學說完全不知道什麼是錄影帶/碟片租售店, 這個年代不是只有 ppstream 嗎? 哎呀呀! 就麻煩去馬路上逛一下吧, 物件導向程式要模型化的東西你最好還是有一些實際接觸的經驗會比較好...

在這個作業中首先我們會探討錄影帶和碟片是否需要為不同類別的問題, 然後我們擴充會員類別成為 VIP 會員類別, 接下來定義一個比較特別的折扣類別來處理各式各樣的商品促銷折扣, 最後實作會員租借商品時的租借記錄以及各分店每日借還記錄報表。 有了這些表示資料的架構之後, 我們進一步實作一些需要的功能。

作業目標:

  1. 運用繼承與多型語法設計程式,使得程式有較好的擴充性

  2. 考慮各種不同的高階實作架構,從效能與擴充性去評斷某一設計的好壞

作業說明:

  1. 在上一次的作業中, 大家都設計了出租商品和錄影帶商店的類別, 下面是兩種可能的設計方法:
        
    左圖是將所有可出租的商品都合併為一個類別, 不論是錄影帶、VCD、或是 DVD 都是這個類別的物件; 右圖則是依照主要商品類別來區分型態, 請在書面報告中舉例說明上面兩種設計各自有什麼樣的優缺點? (你可以考量類別裡是否會有多餘的欄位, 或是對於某些物件才能使用的介面, 或是考慮如果要新增加一種出租項目時的狀況, 或是程式碼的重複, 或是撰寫一些功能時的困難度...)

  2. 假設此家連鎖店某一天開始增加 遊戲光碟 的出租項目, 如果採用上面右圖的設計, 你需要再設計一個功能很類似的類別, 欄位的內容可能稍有不同, 類別的介面可能大同小異, 但是各分店物件裡需要有獨立的容器物件來存放這類的商品, 同時你在製作一般性的搜尋 (例如以商品標題搜尋) 功能裡面就需要替這個類別的商品多增加一部份程式碼, 這是我們在上課時所提到的 "Using code to select code" 的架構,會使得系統的擴充能力變得很差, 所以在這裡請運用繼承的語法, 將各個類別中重複的部份抽離出來成為共同的父類別 --- "出租商品", 設計如下圖的類別架構:
    你的程式中繼承的架構並不強制要求你只有兩層, 如果你覺得需要更細分的話, 你也可以自己設計繼承的架構, 不過希望所有的類別都繼承一個單一的 "出租商品" 類別, 因為這樣的話在 "分店" 的類別裡就可以實作實習時練習過的 "異質容器物件", 同時你也會發現許多查詢的功能變得比較好寫了, 程式碼不需要針對每一搜尋的類別去設計一個了。

  3. 上一次的作業中我們沒有提到會員可以分等級, 這一次的作業裡我們很快地運用繼承來擴充會員類別成為 VIP 會員, 這兩種會員基本上的差異在於折扣, 在不同的時候對於不同的產品有不同的折扣, 當然 VIP 會員的折扣不管怎樣都是比較多的。 由於 VIP 會員這個類別主要和商品的折扣相關, 所以我們配合下述的 "折扣機制" 一起設計。

  4. 因為 ppstream 還有其他 P2P 軟體的關係, 生意真的很不好做, 所以各種促銷的折扣是一定要有的:

    1. 每一件商品在計算租金時都要根據 (商品、顧客等級、日期區間) 三者來決定其折扣數, 有的時候會有多種折扣方案同時適用, 此時如果是 VIP 會員的話, 自動以最高兩個折扣乘起來計算, 如果是一般會員的話 自動以最高折扣數計算。

    2. 結帳時我們假設 商品 和 會員證 都有條碼, 可以很快地輸入 (目前請以手動輸入商品及會員的 ID), 並查詢到此兩個物件。

    3. 將 "折扣" 設計成為一個物件, 每一個 "出租商品" 物件都會參考到所有這個商品可以適用的 "折扣" 物件, (也就是一個 "出租商品" 物件和多個 "折扣" 物件有關聯), 折扣物件是店員每天維護的, 假設有一個圖形界面, 店員可以根據商品種類 (例如所有 VCD)、 劇情分類 (例如所有愛情文藝片)、上架時間 (例如兩週內) 來指定一些商品對於不同等級的會員有某些折扣 (例如:一般會員八折, VIP 會員七折), 店員透過上述介面產生一個 "折扣" 物件, 設定 "折扣的有效期間" 以及 "一般會員的折扣方法" 和 "VIP 會員的折扣方法"。 此時圖形界面程式會搜尋符合要求的商品, 並且在這些商品物件中記錄一指標指向此折扣物件, 未來結帳時,可以運用所有符合的折扣物件來計算該商品的折扣。

    4. 為了進行測試,我們可以設定比較簡單的折扣方案, 例如所有 冒險動作片,在 97/06/01-97/06/30 這段時間內, 一般會員一率八折,VIP 會員七折, 折扣物件可以在你的文字界面裡加一個選項來產生, 然後需要由各分店自行維護所有的折扣物件, 在產生的時候還需要搜尋所有的出租商品, 在符合的商品物件中記錄一指標指向此折扣物件, 這個機制可以完全設計在 "出租商品" 類別中。

    5. 請設計折扣物件的兩個公開界面: double getDiscountNormalMember() 與 double getDiscountVIPMember(), 這兩個界面一個是給一般會員的物件來使用的, 一個是給 VIP 會員的物件使用的。

  5. "出租商品" 這個類別需要提供計算每日租金的界面, 每日計算租金時可以運用這個界面, 把租借商品的會員物件傳入之後可以得到此項商品當天的租金, 這個界面需要運用所有符合的折扣物件, 以及會員物件來計算, 在程式裡為了不需要去判斷會員的種類, 你應該在 "會員" 類別中設計一個 getDiscount() 的虛擬函式, 傳入 "折扣" 物件,呼叫折扣物件的 getDiscountNormalMember() 來得到折扣數, 另外在衍生的 "VIP 會員" 類別中覆載這個函式, 呼叫折扣物件的 getDiscountVIPMember() 來得到折扣數

  6. 在 "分店" 物件中需要維護記錄所有出租資料, 每一筆資料是一個獨立的 "租借記錄" 物件, 記錄出租商品以及租借會員 (以指向會員物件以及出租商品物件的指標來完成), 並且記錄商品借出的日期以及歸還的日期, 以便計算每日的租金所得

  7. 由於系統有時需要查詢會員的所有租借記錄, 因此 "會員" 物件和 "租借記錄" 物件之間的連結建議是雙向的

  8. 完成這個作業之後, 請你在書面報告中說明你的每一個動態多型機制是如何透過繼承與多型指標完成的

  9. 請設計一個列印當日營收報表的功能: 把當天借出的商品與會員資料、 當天歸還的商品與會員資料、 以及計算當天的租金營收資料列印出來

  10. 各個類別的功能你可以自行設計調整, 介面的細部功能也請自行設計

  11. 雖然上面的說明和圖片裡我都用中文來描述類別和物件, 你都寫到第四個作業了, 應該知道這樣的話 compiler 是不會接受的, 你還是要一個一個取你覺得有意義的名字, 再一次強調你的程式中所用到的所有變數名稱, 類別名稱,資料型態名稱, 函式名稱都要是有意義的英文片語, 不要隨便縮寫。 (等你做完應該就會發現我為什麼要用中文了。)

  12. 請使用 VC++ 6.0 完成

  13. 各個類別內請加入適當的單元測試程式碼

  14. 整個應用程式在測試時由於有使用者界面, 請你事先構想好測試的流程, 把所有需要由鍵盤輸入的資料打在命令檔案裡, 最後兩個命令應該是把目前系統狀態存檔, 然後結束應用程式。
    Demo 時運用 DOS 下 myprog << input.txt 的敘述來展示。
    程式結束後,再重新讀入剛才存檔的資料, 然後助教可以操作你的查尋功能來看是否剛才在命令檔案裡的命令有正確執行。

作業繳交:

作業討論區 線上繳交網頁

C++ 程式設計課程 首頁

製作日期: 05/27/2008 by 丁培毅 (Pei-yih Ting)
E-mail: pyting@cs.ntou.edu.tw TEL: 02 24622192x6615
國立台灣海洋大學 電機資訊學院 資訊工程系 Lagoon