本文實例為大家分享了Java購物系統設計與實現代碼,供大家參考,具體內容如下
1. 購物系統的需求分析和類劃分
購物系統本身是一個十分複雜的系統,有很多細節問題如果深究會更加複雜,並且一般購物系統都是網頁類型的,要有一個友好的界面,但是作為一個簡單項目,該項目只是為了給JAVA初學者介紹一下開發的基本思想,以及面向對象時應該怎樣去設計框架和實現流程,所以只是基於eclipse開發的一個簡單的項目,並沒有GUI的參與,並且很多細節問題作為後續研究,整體的設計比較簡單,但是足以說明很多設計思想和設計理念,那麼下面對基本的需求進行分析。
作為一個簡單的購物系統,至少需要具備以下功能(這些功能分佈在不同級的菜單中):
(1)用戶登錄功能、用戶賬號密碼修改功能,暫時不提供註冊功能;
(2)用戶成功登錄後,需要具備客戶信息的管理功能、購物結算功能以及一些抽獎活動等;
(3)客戶信息管理功能下面又可以分出很多功能,比如說:查詢、修改、增加等;
(4)購物結算功能下面又可以分出很多功能,比如說:商品選購、付款、賬單等;
(5)抽獎活動下面又可以設計出多種的抽獎形式,從而進一步劃分為許多新的功能模塊。
(6)在一級菜單中要提供退出系統的功能,在二級菜單中要提供註銷登錄的功能,其他級菜單都要能夠返回上一級菜單。
上面的這些功能都是一些比較基本的功能,那麼如果按照面向流程的思想來設計,就會劃分很多功能模塊,然後按照流程一步步走就行,但是現在我們採用面向對象的思想來設計,那麼應該如何考慮設計框架呢?面向對象的主要思想就是將一些需求抽象為許多類,然後建立這些類之間的聯繫,通過不同類之間的協同合作,就可以實現所有的功能。所以,現在的主要任務就是如何合理地抽像出這些類,以及這些類要實現什麼功能,類之間的聯繫又是什麼?下面通過本次設計的結構對這一過程進行分析。
(1)StartSMS類:用於系統的啟動。我們的系統肯定需要一個啟動類,這個類裡麵包含了main方法,用來啟動這個系統,這個類是最頂層的,所以不能牽涉太多底層的細節實現,只需要實現一些頂層的基本流程就行,主要還是要調用底層其他類的一些方法來實現功能。
(2)Data類:用來存放我們的所有數據信息,本次設計主要存放的是已經預存的一些可供購買的商品信息和已經註冊的會員信息。為什麼需要這個類呢?大家想一想,在面向對象的設計中,我們的數據比較多,肯定不能零散地到處定義、任意修改,這樣會使得系統的聚合程度太低,容易出現很多錯誤,並且難以進行後期功能擴展和錯誤修改,所以我們要把用到的一些公有的數據進行歸類,然後放在一個類中,並且在該類中提供對這些數據進行操作的方法。
(3)Menu類:用於顯示及處理各級菜單。既然我們設計的是一個購物系統,那麼即使再簡單,也需要一個基本的菜單,用來和用戶進行交互,由於菜單的比較多,並且各級菜單之間層層相連,所以我們需要對菜單進行統一管理,故而出現了菜單類。注意,這裡的菜單只是一些頂層的菜單顯示和基本的功能調用,具體底層的算法還是需要更加底層的類來實現的。
(4)Manager類:用於存儲用戶的賬戶和密碼。既然我們需要用戶登錄,那麼肯定需要一個單獨的類來管理用戶的賬戶和密碼,從而使系統的獨立性更強一些。本次設計的用戶只有一個賬戶和密碼,只允許修改賬戶和密碼,但是不允許註冊。
(5)VerifyEqual類:用於驗證登錄信息。這個類相當於是把登錄這項功能抽象成了一個類,這個實現其實並不是非常必要,但是為了使得系統功能劃分更加清晰,所以設計了此類,用來對登錄信息和已有的賬戶和密碼進行校驗,從而給出校驗結果。
(6)CustManagement類:用於客戶信息的管理,該類實現了底層的一些功能,比如說查詢、修改、增加等。當我們進入到客戶信息管理這個菜單的時候,肯定需要對客戶信息進行許多操作,為了方便管理這些操作,並考慮到後續的擴展性,這裡把客戶信息管理的所有功能都抽像出來,放在此類中,上一級菜單通過調用該類中的方法實現客戶信息的管理。
(7)Pay類:用於處理購物和結算操作。該類和上面的類存在的原理基本一致,當客戶選擇進行購物的時候,肯定要有很多操作,比如說買什麼、多少錢、付款、找零等,這些功能比較零碎,所以我們對其進行集中管理,從而抽像出該類,對購物和結算的菜單選項的底層算法進行實現,上一級菜單通過調用該類的方法實現購物和結算功能,並且可以返回上一級菜單。
(8)GiftManagement類:用於處理抽獎活動的相關功能。這個類和(6)、(7)中的類存在的理由基本一致,該類對抽獎活動進行了統一管理,上一級菜單只需要通過調用該類的方法就可以實現抽獎的功能。
(9)Gift類:用於管理禮物。既然設計了抽獎環節,那麼肯定需要禮物,那麼我們會給出什麼樣的禮物呢,我們總不能每一樣禮物都詳細列出來吧,這樣十分冗餘,也很麻煩,所以我們乾脆抽像出一個禮物類,把禮物的一些屬性:禮物名稱和價格等保存成該類的成員變量,然後就可以很方便的管理該類,需要什麼樣的禮物就直接新建一個禮物對象,然後對該對象的屬性進行修改和管理即可,這樣的實現類似於一個接口,但是又和接口完全不一樣,功能差不多。
總之,上面的類都是經過一些功能模塊劃分後抽像出來的,有些地方也並不一定合理,主要還是需要看需求,根據不同的需求制定不同的方案。在這裡,我想就”Gift類“再強調一點,這個類的設計十分符合面向對象的思想,舉個例子來看,如果購物系統中需要很多禮物,比如手機、電腦、移動電源等,那麼如果我們一個個寫這些禮物,會使得系統代碼十分冗餘,因為禮物的屬性基本一樣,所以我們就可以抽象成一個類,從而在需要什麼禮物的時候只定義一個對象,然後賦予一定的屬性即可,比如需要手機、電腦,那麼我們只需要new一個Gift類的對象,然後在需要手機的時候設置其屬性為手機,在需要電腦的時候設置其屬性為電腦,需要什麼設置什麼即可,這樣就使得我們的代碼得到了簡化,也使得結構比較清晰。在更為複雜的系統中,其實禮物用接口來實現更為合理,這樣就可以根據該接口實現不同的禮物類,從而滿足不同的需求,就類似於我們的電腦上的USB接口,只需要這個接口,我們就可以插上很多各種各樣的外圍設備,道理差不多。
2. 購物系統的類之間的關係和流程(用圖示法表示)
下圖是我用Microsoft Office Visio 2003畫圖工具畫出的這9個類之間的關係。
從上圖中可以清晰地看出來各類之間的關係,大致關係和流程如下所述:
(1)StartSMS類是啟動類,內含main方法,這個類裡面定義了VerifyEqual類和Data類的對象,用來存儲數據和驗證信息,同時Data類中包含了Manager類,用來存儲預存的用戶賬號信息,然後在main方法中通過一定的邏輯,去調用Menu類中的showLoginMenu()方法,用於處理一級菜單---登錄修改流程;
(2)如果登錄成功,就調用Menu類中的showMainMenu()方法,用於處理二級菜單---購物系統的主流程,如果登錄失敗3次,就直接退出系統;
(3)在Menu類中的showMainMenu()方法中,通過選擇不同的二級菜單選項,從而調用Menu類中的showCustMMenu()方法來處理客戶信息管理流程或者調用Menu類中的showSendMenu()方法來處理抽獎活動流程,亦或者調用Pay類中的calcPrice()方法來處理購物結算流程;
(4)如果選擇了二級菜單中的客戶信息管理選項,那麼就會調用Menu類中的showCustMMenu()方法,這個方法會調用CustManagement類中的各種方法,用以處理客戶信息管理的不同操作;
(5)如果選擇了二級菜單中的購物結算選項,那麼就會調用Pay類中的calcPrice()方法,從而處理購物結算的流程,注意在Pay類中的getDiscount()方法是用來根據客戶會員信息來計算打折率的;
(6)如果選擇了二級菜單中的真情回饋選項,即抽獎活動,那麼就會調用Menu類中的showSendMenu()方法,這個方法會調用GiftManagement類中的各種方法,用以處理抽獎活動的不同操作;
注意到在CustManagement類和GiftManagement類中都有一個returnLastMenu()方法,該方法是用來返回上一級菜單使用的。
3. 代碼實現
需要說明的一點是這些代碼都應該放在cn.itcast包下。
3.1 StartSMS類
package cn.itcast; import java.util.Scanner; /** * 該類是這個系統的主方法類,用於啟動購物系統* * @author * */ public class StartSMS { /** * 空構造方法* */ public StartSMS() { } /** * 系統主方法* * @param args */ public static void main(String args[]) { // 創建已有的數據類的對象,並初始化已有的商品信息和顧客信息Data data = new Data(); data.initial(); // 創建菜單類的對象Menu menu = new Menu(); // 這裡將初始化的已有數據信息送給了菜單對象menu.setData( data.goodsName, data.goodsPrice, data.custNo, data.custBirth, data.custScore); // 顯示一級菜單,即登錄界面menu.showLoginMenu(); // 該標誌用來判斷是否發生了系統操作錯誤,當操作不當的時候flag為假,從而退出系統,默認為無錯誤boolean flag = true; // 處理整個系統的流程do { // 發生操作錯誤,退出系統if (!flag) break; // 創建驗證用戶登錄的賬戶和密碼是否正確的類的對象,這裡只創建對象,並沒有執行驗證方法VerifyEqual verifyequal = new VerifyEqual(); // 輸入一級菜單中的選擇Scanner scanner = new Scanner(System.in); int i = scanner.nextInt(); // 根據用戶對一級菜單的選擇做出不同的響應,注意這裡就是經典的switch-case的用法switch (i) { case 1: // 用戶選擇"登錄系統" // 定義計數器,表示用戶最多只能嘗試3次,3次輸入錯誤直接退出系統int j = 3; // 處理登錄系統的流程do { if (verifyequal.verify(data.manager.username, data.manager.password)) { // 用戶登錄成功,顯示購物二級菜單! ! ! menu.showMainMenu(); break; } if (j != 1) { // 用戶輸入有誤,還沒有達到3次,允許重新輸入System.out.println("/n用戶名和密碼不匹配,請重新輸入:"); } else { // 3次嘗試結束,設置退出標誌,並退出do-while循環System.out.println("/n您沒有權限進入系統!謝謝!"); flag = false; break; } // 每輸入一次將計數器減1,用於表示已經嘗試了多少次j--; } while (true); break; case 2: // 用戶選擇"更改管理員信息" if (verifyequal.verify(data.manager.username, data.manager.password)) { // 輸入新信息前要先驗證原來的信息,此處表示已經驗證成功System.out.print("請輸入新的用戶名:"); data.manager.username = scanner.next(); System.out.print("請輸入新的密碼:"); data.manager.password = scanner.next(); System.out.println("用戶名和密碼已更改!"); // 信息更改成功,選擇下一步的操作System.out.println("/n請選擇,輸入數字:"); } else { // 信息驗證失敗,設置退出標誌System.out.println("抱歉,你沒有權限修改!"); flag = false; } break; case 3: // 用戶選擇"退出" System.out.println("謝謝您的使用!"); System.exit(0); break; default: // 一級菜單輸入錯誤,需要重新選擇System.out.print("/n輸入有誤!請重新選擇,輸入數字: "); break; } } while (flag); } }3.2 Data類
package cn.itcast; /** * 存放購物系統的初始化數據的數據類,該類只是存放了已有的商品信息和顧客信息* * @author * */ public class Data { /** * 默認構造方法,初始化變量,由於都是數組對像或類對象,所以都需要採用new * */ public Data() { goodsName = new String[50] ; goodsPrice = new double[50] ; custNo = new int[100] ; custBirth = new String[100]; custScore = new int[100] ; manager = new Manager() ; } /** * 初始化該類的數據* */ public void initial() { /*====================添加了初始的7種商品信息====================*/ goodsName [0] = "addidas運動鞋"; goodsPrice[0] = 880D; goodsName [1] = "Kappa網球裙"; goodsPrice[1] = 200D; goodsName [2] = "網球拍"; goodsPrice[2] = 780D; goodsName [3] = "addidasT卹"; goodsPrice[3] = 420.77999999999997D; goodsName [4] = "Nike運動鞋"; goodsPrice[4] = 900D; goodsName [5] = "Kappa網球"; goodsPrice[5] = 45D; goodsName [6] = "KappaT卹"; goodsPrice[6] = 245D; /*====================添加了初始的7個顧客信息====================*/ custNo [0] = 1900; custBirth[0] = "08/05"; custScore[0] = 2000; custNo [1] = 1711; custBirth[1] = "07/13"; custScore[1] = 4000; custNo [2] = 1623; custBirth[2] = "06/26"; custScore[2] = 5000; custNo [3] = 1545; custBirth[3] = "04/08"; custScore[3] = 2200; custNo [4] = 1464; custBirth[4] = "08/16"; custScore[4] = 1000; custNo [5] = 1372; custBirth[5] = "12/23"; custScore[5] = 3000; custNo [6] = 1286; custBirth[6] = "12/21"; custScore[6] = 10080; } /*====================定義該類所擁有的變量====================*/ public String goodsName []; // 商品的名稱public double goodsPrice[]; // 商品的價格public int custNo []; // 顧客的會員號public String custBirth []; // 顧客的生日public int custScore []; // 顧客的積分public Manager manager ; // 管理員類,僅僅存儲了管理員的用戶名和密碼}3.3 Manager類
package cn.itcast; /** * 管理員類,僅僅存儲了管理員的用戶名和密碼* * @author * */ public class Manager { /** * 設置默認的用戶名和密碼* */ public Manager() { username = "itcast"; password = "itcast"; } /*====================定義該類所擁有的變量====================*/ public String username; // 用戶名public String password; // 密碼}3.4 VerifyEqual類
package cn.itcast; import java.util.Scanner; /** * 驗證用戶登錄的賬戶和密碼是否正確的類* * @author * */ public class VerifyEqual { /** * 空構造方法* */ public VerifyEqual() { } /** * 執行驗證的方法* * @param s 用於驗證的正確的用戶名* @param s1 用於驗證的正確的密碼* @return */ public boolean verify(String s, String s1) { // 由用戶輸入用戶名System.out.print("請輸入用戶名:"); Scanner scanner = new Scanner(System.in); String s2 = scanner.next(); // 由用戶輸入密碼System.out.print("請輸入密碼:"); scanner = new Scanner(System.in); String s3 = scanner.next(); // 判斷用戶輸入的信息是否和已有的信息一致return s2.equals(s) && s1.equals(s3); } }3.5 Menu類
package cn.itcast; import java.util.Scanner; /** * 菜單類,用於顯示所有級菜單供用戶選擇* * @author * */ public class Menu { /** * 空構造方法* */ public Menu() { } /** * 設置菜單類中的數據信息* * @param as * @param ad * @param ai * @param as1 * @param ai1 */ public void setData(String as[], double ad[], int ai[], String as1[], int ai1[]) { goodsName = as; goodsPrice = ad; custNo = ai; custBirth = as1; custScore = ai1; } /** * 顯示一級菜單,即登錄界面* */ public void showLoginMenu() { System.out.println("/n/n/t/t/t 歡迎使用itcast購物管理系統1.0版/n/n"); System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */n"); System.out.println("/t/t/t/t 1. 登錄系統/n/n"); System.out.println("/t/t/t/t 2. 更改管理員信息/n/n"); System.out.println("/t/t/t/t 3. 退出/n/n"); System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */n"); System.out.print("請選擇,輸入數字:"); } /** * 顯示二級菜單,即係統的主菜單,這個方法裡麵包含了對這個菜單處理的所有流程* */ public void showMainMenu() { // 顯示二級菜單,即係統的主菜單System.out.println("/n/n/t/t/t/t歡迎使用購物管理系統/n"); System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */n"); System.out.println("/t/t/t/t 1. 客戶信息管理/n"); System.out.println("/t/t/t/t 2. 購物結算/n"); System.out.println("/t/t/t/t 3. 真情回饋/n"); System.out.println("/t/t/t/t 4. 註銷/n"); System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */n"); // 用戶選擇服務項目System.out.print("請選擇,輸入數字:"); Scanner scanner = new Scanner(System.in); // 設置標誌用於控制循環boolean flag = false; do { String s = scanner.next(); // 用戶選擇"客戶信息管理" if (s.equals("1")) { // 顯示客戶信息管理菜單並處理這個菜單的整個流程,當這個流程處理完showCustMMenu(); break; } // 用戶選擇"購物結算" if (s.equals("2")) { // 定義購物結算類的對象,並處理整個購物結算的流程Pay pay = new Pay(); pay.setData(goodsName, goodsPrice, custNo, custBirth, custScore); pay.calcPrice(); break; } // 用戶選擇"真情回饋" if (s.equals("3")) { // 處理真情回饋的整個處理流程showSendGMenu(); break; } // 用戶選擇"註銷" if (s.equals("4")) { // 顯示一級菜單,此時會返回至StartSMS類中的一級菜單處理流程showLoginMenu(); break; } System.out.print("輸入錯誤,請重新輸入數字:"); flag = false; } while (!flag); } /** * 顯示三級菜單-客戶信息管理,並處理所有客戶信息管理的流程* */ public void showCustMMenu() { System.out.println("購物管理系統> 客戶信息管理/n"); System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */n"); System.out.println("/t/t/t/t 1. 顯示所有客戶信息/n"); System.out.println("/t/t/t/t 2. 添加客戶信息/n"); System.out.println("/t/t/t/t 3. 修改客戶信息/n"); System.out.println("/t/t/t/t 4. 查詢客戶信息/n"); System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */n"); System.out.print("請選擇,輸入數字或按'n'返回上一級菜單:"); Scanner scanner = new Scanner(System.in); boolean flag = true; do { // 創建客戶信息管理對象,並設置數據,這裡的數據還是原始的那些數據CustManagement custmanagement = new CustManagement(); custmanagement.setData(goodsName, goodsPrice, custNo, custBirth, custScore); String s = scanner.next(); // 客戶選擇"顯示所有客戶信息" if (s.equals("1")) { custmanagement.show(); break; } // 客戶選擇"添加客戶信息" if (s.equals("2")) { custmanagement.add(); break; } // 客戶選擇"修改客戶信息" if (s.equals("3")) { custmanagement.modify(); break; } // 客戶選擇"查詢客戶信息" if (s.equals("4")) { custmanagement.search(); break; } // 客戶選擇"返回上一級菜單" if (s.equals("n")) { showMainMenu(); break; } System.out.println("輸入錯誤, 請重新輸入數字:"); flag = false; } while (!flag); } /** * 顯示三級菜單-真情回饋,並處理所有真情回饋的流程* */ public void showSendGMenu() { System.out.println("購物管理系統> 真情回饋/n"); System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */n"); System.out.println("/t/t/t/t 1. 幸運大放送/n"); System.out.println("/t/t/t/t 2. 幸運抽獎/n"); System.out.println("/t/t/t/t 3. 生日問候/n"); System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */n"); System.out.print("請選擇,輸入數字或按'n'返回上一級菜單:"); Scanner scanner = new Scanner(System.in); // 創建禮物管理對象,並設置數據,這裡的數據還是原始的那些數據GiftManagement giftmanagement = new GiftManagement(); giftmanagement.setData(goodsName, goodsPrice, custNo, custBirth, custScore); boolean flag = true; do { String s = scanner.next(); // 客戶選擇"幸運大放送" if (s.equals("1")) { giftmanagement.sendGoldenCust(); break; } // 客戶選擇"幸運抽獎" if (s.equals("2")) { giftmanagement.sendLuckyCust(); break; } // 客戶選擇"生日問候" if (s.equals("3")) { giftmanagement.sendBirthCust(); break; } // 客戶選擇"返回上一級菜單" if (s.equals("n")) { showMainMenu(); break; } System.out.println("輸入錯誤, 請重新輸入數字:"); flag = false; } while (!flag); } /*====================定義該類所擁有的變量====================*/ public String goodsName []; // 商品的名稱public double goodsPrice[]; // 商品的價格public int custNo []; // 顧客的會員號public String custBirth []; // 顧客的生日public int custScore []; // 顧客的積分}3.6 CustManagement類
package cn.itcast; import java.util.Scanner; /** * 顧客信息管理類* * @author * */ public class CustManagement { /** * 空構造方法* */ public CustManagement() { } /** * 設置顧客信息管理類的數據信息* * @param as * @param ad * @param ai * @param as1 * @param ai1 */ public void setData(String as[], double ad[], int ai[], String as1[], int ai1[]) { goodsName = as; goodsPrice = ad; custNo = ai; custBirth = as1; custScore = ai1; } /** * 返回上一級菜單,即二級菜單-客戶信息管理菜單* */ public void returnLastMenu() { System.out.print("/n/n請按'n'返回上一級菜單:"); Scanner scanner = new Scanner(System.in); boolean flag = true; do if (scanner.next().equals("n")) { // 返回上一級菜單,這里新建了一個菜單對象,只是在用戶看來其實還是同樣的處理流程, // 不過對於程序來說卻又開始了一個新的二級菜單處理流程Menu menu = new Menu(); menu.setData(goodsName, goodsPrice, custNo, custBirth, custScore); menu.showCustMMenu(); } else { System.out.print("輸入錯誤, 請重新'n'返回上一級菜單:"); flag = false; } while (!flag); } /** * 添加客戶信息* */ public void add() { System.out.println("購物管理系統> 客戶信息管理> 添加客戶信息/n/n"); Scanner scanner = new Scanner(System.in); System.out.print("請輸入會員號(<4位整數>):"); int i = scanner.nextInt(); System.out.print("請輸入會員生日(月/日<用兩位數表示>):"); String s = scanner.next(); System.out.print("請輸入積分:"); int j = scanner.nextInt(); int k = -1; int l = 0; do { if (l >= custNo.length) break; // 尋找數組中的第一個空位置,用來存儲新的顧客信息if (custNo[l] == 0) { k = l; break; } l++; } while (true); custNo [k] = i; custBirth[k] = s; custScore[k] = j; System.out.println("新會員添加成功!"); // 返回上一級菜單returnLastMenu(); } /** * 修改客戶信息* */ public void modify() { System.out.println("購物管理系統> 客戶信息管理> 修改客戶信息/n/n"); System.out.print("請輸入會員號:"); Scanner scanner = new Scanner(System.in); int i = scanner.nextInt(); System.out.println(" 會員號生日積分"); System.out.println("------------|------------|---------------"); int j = -1; int k = 0; do { if (k >= custNo.length) break; // 顯示該會員的信息if (custNo[k] == i) { System.out.println((new StringBuilder()).append(custNo[k]) .append("/t/t").append(custBirth[k]).append("/t/t") .append(custScore[k]).toString()); j = k; break; } k++; } while (true); // 該會員存在,則進行修改信息流程if (j != -1) { System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */n"); System.out.println("/t/t/t/t1.修改會員生日./n"); System.out.println("/t/t/t/t2.修改會員積分./n"); System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */n"); System.out.print("請選擇,輸入數字:"); switch (scanner.nextInt()) { case 1: // "修改會員生日" System.out.print("請輸入修改後的生日:"); custBirth[j] = scanner.next(); System.out.println("生日信息已更改!"); break; case 2: // "修改會員積分" System.out.print("請輸入修改後的會員積分:"); custScore[j] = scanner.nextInt(); System.out.println("會員積分已更改!"); break; } } else { System.out.println("抱歉,沒有你查詢的會員。"); } // 返回上一級菜單returnLastMenu(); } /** * 查詢客戶信息* */ public void search() { System.out.println("購物管理系統> 客戶信息管理> 查詢客戶信息/n"); Scanner scanner = new Scanner(System.in); for (String s = "y"; s.equals("y"); s = scanner.next()) { System.out.print("請輸入會員號:"); int i = scanner.nextInt(); System.out.println(" 會員號生日積分"); System.out.println("------------|------------|---------------"); boolean flag = false; int j = 0; do { if (j >= custNo.length) break; // 顯示該會員的信息if (custNo[j] == i) { System.out.println((new StringBuilder()).append(custNo[j]) .append("/t/t").append(custBirth[j]).append("/t/t") .append(custScore[j]).toString()); flag = true; break; } j++; } while (true); if (!flag) System.out.println("抱歉,沒有你查詢的會員信息。"); System.out.print("/n要繼續查詢嗎(y/n):"); } // 返回上一級菜單returnLastMenu(); } /** * 顯示所有客戶信息* */ public void show() { System.out.println("購物管理系統> 客戶信息管理> 顯示客戶信息/n/n"); System.out.println(" 會員號生日積分"); System.out.println("------------|------------|---------------"); int i = custNo.length; for (int j = 0; j < i && custNo[j] != 0; j++) System.out.println((new StringBuilder()).append(custNo[j]).append( "/t/t").append(custBirth[j]).append("/t/t").append( custScore[j]).toString()); // 返回上一級菜單returnLastMenu(); } /*====================定義該類所擁有的變量====================*/ public String goodsName []; // 商品的名稱public double goodsPrice[]; // 商品的價格public int custNo []; // 顧客的會員號public String custBirth []; // 顧客的生日public int custScore []; // 顧客的積分}3.7 Pay類
package cn.itcast; import java.util.Scanner; /** * 處理顧客購買商品以及結算的類* * @author * */ public class Pay { /** * 空構造方法* */ public Pay() { } /** * 設置購物結算類的數據信息* * @param as * @param ad * @param ai * @param as1 * @param ai1 */ public void setData(String as[], double ad[], int ai[], String as1[], int ai1[]) { goodsName = as; goodsPrice = ad; custNo = ai; custBirth = as1; custScore = ai1; } /** * 根據會員信息確定折扣率* * @param i * @param ai * @param ai1 * @return */ public double getDiscount(int i, int ai[], int ai1[]) { int j = -1; int k = 0; do { if (k >= ai.length) break; if (i == ai[k]) { j = k; break; } k++; } while (true); double d; if (ai1[j] < 1000) d = 0.94999999999999996D; else if (1000 <= ai1[j] && ai1[j] < 2000) d = 0.90000000000000002D; else if (2000 <= ai1[j] && ai1[j] < 3000) d = 0.84999999999999998D; else if (3000 <= ai1[j] && ai1[j] < 4000) d = 0.80000000000000004D; else if (4000 <= ai1[j] && ai1[j] < 6000) d = 0.75D; else if (6000 <= ai1[j] && ai1[j] < 8000) d = 0.69999999999999996D; else d = 0.59999999999999998D; return d; } /** * 該類的關鍵方法,用於處理購物和結算* */ public void calcPrice() { String s2 = ""; double d1 = 0.0D; double d2 = 0.0D; int l = 0; double d4 = 0; System.out.println("購物管理系統> 購物結算/n/n"); System.out.println("*************************************"); System.out.println("請選擇購買的商品編號:"); // 顯示所有的可購買商品信息,這裡的信息就是最初的那些初始化商品數據for (l = 0; l < goodsName.length && goodsName[l] != null; l++) { d4++; System.out.println((new StringBuilder()).append(d4).append(": ") .append(goodsName[l]).append("/t").toString()); } System.out.println("*************************************/n"); Scanner scanner = new Scanner(System.in); System.out.print("/t請輸入會員號:"); int i = scanner.nextInt(); // 根據會員信息獲取打折信息d4 = getDiscount(i, custNo, custScore); String s1; do { System.out.print("/t請輸入商品編號:"); int j = scanner.nextInt(); System.out.print("/t請輸入數目:"); int k = scanner.nextInt(); double d = goodsPrice[j - 1]; String s = goodsName[j - 1]; d1 += d * (double) k; s2 = (new StringBuilder()).append(s2).append("/n").append(s) .append("/t").append("¥").append(d).append("/t/t") .append(k).append("/t/t").append("¥") .append(d * (double) k).append("/t").toString(); System.out.print("/t是否繼續(y/n)"); s1 = scanner.next(); } while (s1.equals("y")); d2 = d1 * d4; // 打折後的總價System.out.println("/n"); System.out.println("*****************消費清單*********************"); System.out.println("物品/t/t單價/t/t個數/t/t金額/t"); System.out.print(s2); System.out.println((new StringBuilder()).append("/n折扣:/t").append(d4).toString()); System.out.println((new StringBuilder()).append("金額總計:/t¥").append(d2).toString()); System.out.print("實際交費:/t¥"); double d3 = scanner.nextDouble(); System.out.println((new StringBuilder()).append("找錢:/t¥").append(d3 - d2).toString()); int i1 = ((int) d2 / 100) * 3; int j1 = 0; do { if (j1 >= custNo.length) break; if (custNo[j1] == i) { custScore[j1] = custScore[j1] + i1; System.out.println((new StringBuilder()).append("本次購物所獲的積分是: ") .append(i1).toString()); break; } j1++; } while (true); System.out.print("/n請'n'返回上一級菜單:"); if (scanner.next().equals("n")) { // 返回上一級菜單,這里新建了一個菜單對象,只是在用戶看來其實還是同樣的處理流程, // 不過對於程序來說卻又開始了一個新的二級菜單處理流程Menu menu = new Menu(); menu.setData(goodsName, goodsPrice, custNo, custBirth, custScore); menu.showMainMenu(); } } /*====================定義該類所擁有的變量====================*/ public String goodsName []; // 商品的名稱public double goodsPrice[]; // 商品的價格public int custNo []; // 顧客的會員號public String custBirth []; // 顧客的生日public int custScore []; // 顧客的積分}3.8 GiftManagement類
package cn.itcast; import java.util.Scanner; /** * 禮物管理類* * @author * */ public class GiftManagement { /** * 空構造方法* */ public GiftManagement() { } /** * 設置禮物管理類的數據信息* * @param as * @param ad * @param ai * @param as1 * @param ai1 */ public void setData(String as[], double ad[], int ai[], String as1[], int ai1[]) { goodsName = as; goodsPrice = ad; custNo = ai; custBirth = as1; custScore = ai1; } /** * 返回上一級菜單,即二級菜單-真情回饋菜單* */ public void returnLastMenu() { System.out.print("/n/n請按'n'返回上一級菜單:"); Scanner scanner = new Scanner(System.in); boolean flag = true; do if (scanner.next().equals("n")) { // 返回上一級菜單,這里新建了一個菜單對象,只是在用戶看來其實還是同樣的處理流程, // 不過對於程序來說卻又開始了一個新的二級菜單處理流程Menu menu = new Menu(); menu.setData(goodsName, goodsPrice, custNo, custBirth, custScore); menu.showCustMMenu(); } else { System.out.print("輸入錯誤, 請重新'n'返回上一級菜單:"); flag = false; } while (!flag); } /** * 生日問候* */ public void sendBirthCust() { System.out.println("購物管理系統> 生日問候/n/n"); System.out.print("請輸入今天的日期(月/日<用兩位表示>):"); Scanner scanner = new Scanner(System.in); String s = scanner.next(); System.out.println(s); String s1 = ""; boolean flag = false; for (int i = 0; i < custBirth.length; i++) if (custBirth[i] != null && custBirth[i].equals(s)) { s1 = (new StringBuilder()).append(s1).append(custNo[i]).append( "/n").toString(); flag = true; } // 這裡的禮物是固定的,所以沒有用禮物類if (flag) { System.out.println("過生日的會員是:"); System.out.println(s1); System.out.println("恭喜!獲贈MP3一個!"); } else { System.out.println("今天沒有過生日的會員!"); } // 返回上一級菜單returnLastMenu(); } /** * 幸運抽獎,注意這裡是隨機的抽獎,所以需要隨機數,只需要自己制定一個抽獎規則就可以* */ public void sendLuckyCust() { System.out.println("購物管理系統> 幸運抽獎/n/n"); System.out.print("是否開始(y/n):"); Scanner scanner = new Scanner(System.in); if (scanner.next().equals("y")) { int i = (int) (Math.random() * 10D); // 產生一個隨機數String s = ""; boolean flag = false; for (int k = 0; k < custNo.length && custNo[k] != 0; k++) { // 拿隨機數與顧客會員號的相應結果進行比較,從而判斷是否有顧客中獎int j = (custNo[k] / 100) % 10; if (j == i) { s = (new StringBuilder()).append(s).append(custNo[k]) .append("/t").toString(); flag = true; } } // 固定的獎品,所以不需要禮物類if (flag) System.out.println((new StringBuilder()).append("幸運客戶獲贈MP3:") .append(s).toString()); else System.out.println("無幸運客戶。"); } // 返回上一級菜單returnLastMenu(); } /** * 幸運大放送,取積分最高的會員作為幸運者,送其獎品* */ public void sendGoldenCust() { System.out.println("購物管理系統> 幸運大放送/n/n"); int i = 0; int j = custScore[0]; for (int k = 0; k < custScore.length && custScore[k] != 0; k++) { // 找到積分最高的會員if (custScore[k] > j) { j = custScore[k]; i = k; } } System.out.println((new StringBuilder()).append("具有最高積分的會員是: ").append( custNo[i]).append("/t").append(custBirth[i]).append("/t") .append(custScore[i]).toString()); // 創建禮物類,並對禮物信息進行設置,這裡的禮物是固定的信息Gift gift = new Gift(); gift.name = "蘋果筆記本電腦"; gift.price = 12000D; System.out.print("恭喜!獲贈禮品: "); System.out.println(gift); // 返回上一級菜單returnLastMenu(); } /*====================定義該類所擁有的變量====================*/ public String goodsName []; // 商品的名稱public double goodsPrice[]; // 商品的價格public int custNo []; // 顧客的會員號public String custBirth []; // 顧客的生日public int custScore []; // 顧客的積分}3.9 Gift類
package cn.itcast; /** * 用來存放真情回饋中的禮物的類*/ public class Gift { /** * 空構造方法* */ public Gift() { } /** * 根據禮物對象的變量返回禮物的全部信息* */ public String toString() { return (new StringBuilder()).append("一個價值¥").append(price) .append("的").append(name).toString(); } /*====================定義該類所擁有的變量====================*/ public String name ; // 禮物名字public double price; // 禮物價格}3.10 代碼總結
從上面的9個類的代碼來看,有一些需要注意的地方:
(1)在許多類中都定義了與Data中基本一樣的成員變量,只是沒有Manager對象而已,這是為了讓數據一層層保存和傳遞,通過setData()方法實現,不過這種方法其實並不是很好,並且一般來說成員變量應該最好設置為私有的,這裡這樣的設計是為了操作方便,使系統更簡單一些,安全性不好。
(2)注意到所有要進行字符串拼接的地方都使用JAVA中的StringBuilder類,這是為了高效處理字符串拼接,防止String類帶來的拼接數據冗餘。
(3)這些設計中的流程並不是非常合理,大家可以自己的需要進行修改。
(4)代碼中基本上沒有考慮異常時的處理,所以當輸入時出現錯誤的時候,普通錯誤可以進行重新輸入,但是如果出現不匹配等錯誤,直接會出現異常,從而退出系統,這些也是本設計的缺陷,可以通過正則表達式等來完善一些。
總之,給出的代碼僅供參考,大家可以根據需要進行修改,這些代碼都是經過驗證的,可以直接運行。
4. 總結
這個設計只是為了說明一些基本的設計思想和設計理念,以及設計過程中需要考慮的問題,主要還是為了說明怎樣用面向對象的思想去解決現實生活中的問題,所以設計相對簡單,不過希望大家可以通過這個設計理解這些基本的思想,從而幫助大家理想面向對象的基本思想。
總之,語言只是一種解決問題的工具,大家可以用C++、C#等其他語言來實現這一系統,只要有良好的設計理念和設計思想就可以。再次強調,本設計僅供參考,歡迎大家參與討論,有錯誤的地方歡迎大家指正,謝謝。