Java購物系統(tǒng)設(shè)計與實現(xiàn)
本文實例為大家分享了Java購物系統(tǒng)設(shè)計與實現(xiàn)代碼,供大家參考,具體內(nèi)容如下
1. 購物系統(tǒng)的需求分析和類劃分
購物系統(tǒng)本身是一個十分復(fù)雜的系統(tǒng),有很多細(xì)節(jié)問題如果深究會更加復(fù)雜,并且一般購物系統(tǒng)都是網(wǎng)頁類型的,要有一個友好的界面,但是作為一個簡單項目,該項目只是為了給JAVA初學(xué)者介紹一下開發(fā)的基本思想,以及面向?qū)ο髸r應(yīng)該怎樣去設(shè)計框架和實現(xiàn)流程,所以只是基于eclipse開發(fā)的一個簡單的項目,并沒有GUI的參與,并且很多細(xì)節(jié)問題作為后續(xù)研究,整體的設(shè)計比較簡單,但是足以說明很多設(shè)計思想和設(shè)計理念,那么下面對基本的需求進(jìn)行分析。
作為一個簡單的購物系統(tǒng),至少需要具備以下功能(這些功能分布在不同級的菜單中):
(1)用戶登錄功能、用戶賬號密碼修改功能,暫時不提供注冊功能;
(2)用戶成功登錄后,需要具備客戶信息的管理功能、購物結(jié)算功能以及一些抽獎活動等;
(3)客戶信息管理功能下面又可以分出很多功能,比如說:查詢、修改、增加等;
(4)購物結(jié)算功能下面又可以分出很多功能,比如說:商品選購、付款、賬單等;
(5)抽獎活動下面又可以設(shè)計出多種的抽獎形式,從而進(jìn)一步劃分為許多新的功能模塊。
(6)在一級菜單中要提供退出系統(tǒng)的功能,在二級菜單中要提供注銷登錄的功能,其他級菜單都要能夠返回上一級菜單。
上面的這些功能都是一些比較基本的功能,那么如果按照面向流程的思想來設(shè)計,就會劃分很多功能模塊,然后按照流程一步步走就行,但是現(xiàn)在我們采用面向?qū)ο蟮乃枷雭碓O(shè)計,那么應(yīng)該如何考慮設(shè)計框架呢?面向?qū)ο蟮闹饕枷刖褪菍⒁恍┬枨蟪橄鬄樵S多類,然后建立這些類之間的聯(lián)系,通過不同類之間的協(xié)同合作,就可以實現(xiàn)所有的功能。所以,現(xiàn)在的主要任務(wù)就是如何合理地抽象出這些類,以及這些類要實現(xiàn)什么功能,類之間的聯(lián)系又是什么?下面通過本次設(shè)計的結(jié)構(gòu)對這一過程進(jìn)行分析。
(1)StartSMS類:用于系統(tǒng)的啟動。我們的系統(tǒng)肯定需要一個啟動類,這個類里面包含了main方法,用來啟動這個系統(tǒng),這個類是最頂層的,所以不能牽涉太多底層的細(xì)節(jié)實現(xiàn),只需要實現(xiàn)一些頂層的基本流程就行,主要還是要調(diào)用底層其他類的一些方法來實現(xiàn)功能。
(2)Data類:用來存放我們的所有數(shù)據(jù)信息,本次設(shè)計主要存放的是已經(jīng)預(yù)存的一些可供購買的商品信息和已經(jīng)注冊的會員信息。為什么需要這個類呢?大家想一想,在面向?qū)ο蟮脑O(shè)計中,我們的數(shù)據(jù)比較多,肯定不能零散地到處定義、任意修改,這樣會使得系統(tǒng)的聚合程度太低,容易出現(xiàn)很多錯誤,并且難以進(jìn)行后期功能擴(kuò)展和錯誤修改,所以我們要把用到的一些公有的數(shù)據(jù)進(jìn)行歸類,然后放在一個類中,并且在該類中提供對這些數(shù)據(jù)進(jìn)行操作的方法。
(3)Menu類:用于顯示及處理各級菜單。既然我們設(shè)計的是一個購物系統(tǒng),那么即使再簡單,也需要一個基本的菜單,用來和用戶進(jìn)行交互,由于菜單的比較多,并且各級菜單之間層層相連,所以我們需要對菜單進(jìn)行統(tǒng)一管理,故而出現(xiàn)了菜單類。注意,這里的菜單只是一些頂層的菜單顯示和基本的功能調(diào)用,具體底層的算法還是需要更加底層的類來實現(xiàn)的。
(4)Manager類:用于存儲用戶的賬戶和密碼。既然我們需要用戶登錄,那么肯定需要一個單獨的類來管理用戶的賬戶和密碼,從而使系統(tǒng)的獨立性更強(qiáng)一些。本次設(shè)計的用戶只有一個賬戶和密碼,只允許修改賬戶和密碼,但是不允許注冊。
(5)VerifyEqual類:用于驗證登錄信息。這個類相當(dāng)于是把登錄這項功能抽象成了一個類,這個實現(xiàn)其實并不是非常必要,但是為了使得系統(tǒng)功能劃分更加清晰,所以設(shè)計了此類,用來對登錄信息和已有的賬戶和密碼進(jìn)行校驗,從而給出校驗結(jié)果。
(6)CustManagement類:用于客戶信息的管理,該類實現(xiàn)了底層的一些功能,比如說查詢、修改、增加等。當(dāng)我們進(jìn)入到客戶信息管理這個菜單的時候,肯定需要對客戶信息進(jìn)行許多操作,為了方便管理這些操作,并考慮到后續(xù)的擴(kuò)展性,這里把客戶信息管理的所有功能都抽象出來,放在此類中,上一級菜單通過調(diào)用該類中的方法實現(xiàn)客戶信息的管理。
(7)Pay類:用于處理購物和結(jié)算操作。該類和上面的類存在的原理基本一致,當(dāng)客戶選擇進(jìn)行購物的時候,肯定要有很多操作,比如說買什么、多少錢、付款、找零等,這些功能比較零碎,所以我們對其進(jìn)行集中管理,從而抽象出該類,對購物和結(jié)算的菜單選項的底層算法進(jìn)行實現(xiàn),上一級菜單通過調(diào)用該類的方法實現(xiàn)購物和結(jié)算功能,并且可以返回上一級菜單。
(8)GiftManagement類:用于處理抽獎活動的相關(guān)功能。這個類和(6)、(7)中的類存在的理由基本一致,該類對抽獎活動進(jìn)行了統(tǒng)一管理,上一級菜單只需要通過調(diào)用該類的方法就可以實現(xiàn)抽獎的功能。
(9)Gift類:用于管理禮物。既然設(shè)計了抽獎環(huán)節(jié),那么肯定需要禮物,那么我們會給出什么樣的禮物呢,我們總不能每一樣禮物都詳細(xì)列出來吧,這樣十分冗余,也很麻煩,所以我們干脆抽象出一個禮物類,把禮物的一些屬性:禮物名稱和價格等保存成該類的成員變量,然后就可以很方便的管理該類,需要什么樣的禮物就直接新建一個禮物對象,然后對該對象的屬性進(jìn)行修改和管理即可,這樣的實現(xiàn)類似于一個接口,但是又和接口完全不一樣,功能差不多。
總之,上面的類都是經(jīng)過一些功能模塊劃分后抽象出來的,有些地方也并不一定合理,主要還是需要看需求,根據(jù)不同的需求制定不同的方案。在這里,我想就”Gift類“再強(qiáng)調(diào)一點,這個類的設(shè)計十分符合面向?qū)ο蟮乃枷?,舉個例子來看,如果購物系統(tǒng)中需要很多禮物,比如手機(jī)、電腦、移動電源等,那么如果我們一個個寫這些禮物,會使得系統(tǒng)代碼十分冗余,因為禮物的屬性基本一樣,所以我們就可以抽象成一個類,從而在需要什么禮物的時候只定義一個對象,然后賦予一定的屬性即可,比如需要手機(jī)、電腦,那么我們只需要new一個Gift類的對象,然后在需要手機(jī)的時候設(shè)置其屬性為手機(jī),在需要電腦的時候設(shè)置其屬性為電腦,需要什么設(shè)置什么即可,這樣就使得我們的代碼得到了簡化,也使得結(jié)構(gòu)比較清晰。在更為復(fù)雜的系統(tǒng)中,其實禮物用接口來實現(xiàn)更為合理,這樣就可以根據(jù)該接口實現(xiàn)不同的禮物類,從而滿足不同的需求,就類似于我們的電腦上的USB接口,只需要這個接口,我們就可以插上很多各種各樣的外圍設(shè)備,道理差不多。
2. 購物系統(tǒng)的類之間的關(guān)系和流程(用圖示法表示)
下圖是我用Microsoft Office Visio 2003畫圖工具畫出的這9個類之間的關(guān)系。

從上圖中可以清晰地看出來各類之間的關(guān)系,大致關(guān)系和流程如下所述:
(1)StartSMS類是啟動類,內(nèi)含main方法,這個類里面定義了VerifyEqual類和Data類的對象,用來存儲數(shù)據(jù)和驗證信息,同時Data類中包含了Manager類,用來存儲預(yù)存的用戶賬號信息,然后在main方法中通過一定的邏輯,去調(diào)用Menu類中的showLoginMenu()方法,用于處理一級菜單---登錄修改流程;
(2)如果登錄成功,就調(diào)用Menu類中的showMainMenu()方法,用于處理二級菜單---購物系統(tǒng)的主流程,如果登錄失敗3次,就直接退出系統(tǒng);
(3)在Menu類中的showMainMenu()方法中,通過選擇不同的二級菜單選項,從而調(diào)用Menu類中的showCustMMenu()方法來處理客戶信息管理流程或者調(diào)用Menu類中的showSendMenu()方法來處理抽獎活動流程,亦或者調(diào)用Pay類中的calcPrice()方法來處理購物結(jié)算流程;
(4)如果選擇了二級菜單中的客戶信息管理選項,那么就會調(diào)用Menu類中的showCustMMenu()方法,這個方法會調(diào)用CustManagement類中的各種方法,用以處理客戶信息管理的不同操作;
(5)如果選擇了二級菜單中的購物結(jié)算選項,那么就會調(diào)用Pay類中的calcPrice()方法,從而處理購物結(jié)算的流程,注意在Pay類中的getDiscount()方法是用來根據(jù)客戶會員信息來計算打折率的;
(6)如果選擇了二級菜單中的真情回饋選項,即抽獎活動,那么就會調(diào)用Menu類中的showSendMenu()方法,這個方法會調(diào)用GiftManagement類中的各種方法,用以處理抽獎活動的不同操作;
注意到在CustManagement類和GiftManagement類中都有一個returnLastMenu()方法,該方法是用來返回上一級菜單使用的。
3. 代碼實現(xiàn)
需要說明的一點是這些代碼都應(yīng)該放在cn.itcast包下。
3.1 StartSMS類
package cn.itcast;
import java.util.Scanner;
/**
* 該類是這個系統(tǒng)的主方法類,用于啟動購物系統(tǒng)
*
* @author
*
*/
public class StartSMS {
/**
* 空構(gòu)造方法
*
*/
public StartSMS() {
}
/**
* 系統(tǒng)主方法
*
* @param args
*/
public static void main(String args[]) {
// 創(chuàng)建已有的數(shù)據(jù)類的對象,并初始化已有的商品信息和顧客信息
Data data = new Data();
data.initial();
// 創(chuàng)建菜單類的對象
Menu menu = new Menu();
// 這里將初始化的已有數(shù)據(jù)信息送給了菜單對象
menu.setData(
data.goodsName,
data.goodsPrice,
data.custNo,
data.custBirth,
data.custScore);
// 顯示一級菜單,即登錄界面
menu.showLoginMenu();
// 該標(biāo)志用來判斷是否發(fā)生了系統(tǒng)操作錯誤,當(dāng)操作不當(dāng)?shù)臅r候flag為假,從而退出系統(tǒng),默認(rèn)為無錯誤
boolean flag = true;
// 處理整個系統(tǒng)的流程
do {
// 發(fā)生操作錯誤,退出系統(tǒng)
if (!flag)
break;
// 創(chuàng)建驗證用戶登錄的賬戶和密碼是否正確的類的對象,這里只創(chuàng)建對象,并沒有執(zhí)行驗證方法
VerifyEqual verifyequal = new VerifyEqual();
// 輸入一級菜單中的選擇
Scanner scanner = new Scanner(System.in);
int i = scanner.nextInt();
// 根據(jù)用戶對一級菜單的選擇做出不同的響應(yīng),注意這里就是經(jīng)典的switch-case的用法
switch (i) {
case 1: // 用戶選擇"登錄系統(tǒng)"
// 定義計數(shù)器,表示用戶最多只能嘗試3次,3次輸入錯誤直接退出系統(tǒng)
int j = 3;
// 處理登錄系統(tǒng)的流程
do {
if (verifyequal.verify(data.manager.username,
data.manager.password)) {
// 用戶登錄成功,顯示購物二級菜單?。。?
menu.showMainMenu();
break;
}
if (j != 1) {
// 用戶輸入有誤,還沒有達(dá)到3次,允許重新輸入
System.out.println("\n用戶名和密碼不匹配,請重新輸入:");
} else {
// 3次嘗試結(jié)束,設(shè)置退出標(biāo)志,并退出do-while循環(huán)
System.out.println("\n您沒有權(quán)限進(jìn)入系統(tǒng)!謝謝!");
flag = false;
break;
}
// 每輸入一次將計數(shù)器減1,用于表示已經(jīng)嘗試了多少次
j--;
} while (true);
break;
case 2: // 用戶選擇"更改管理員信息"
if (verifyequal.verify(data.manager.username,
data.manager.password)) {
// 輸入新信息前要先驗證原來的信息,此處表示已經(jīng)驗證成功
System.out.print("請輸入新的用戶名:");
data.manager.username = scanner.next();
System.out.print("請輸入新的密碼:");
data.manager.password = scanner.next();
System.out.println("用戶名和密碼已更改!");
// 信息更改成功,選擇下一步的操作
System.out.println("\n請選擇,輸入數(shù)字:");
} else {
// 信息驗證失敗,設(shè)置退出標(biāo)志
System.out.println("抱歉,你沒有權(quán)限修改!");
flag = false;
}
break;
case 3: // 用戶選擇"退出"
System.out.println("謝謝您的使用!");
System.exit(0);
break;
default: // 一級菜單輸入錯誤,需要重新選擇
System.out.print("\n輸入有誤!請重新選擇,輸入數(shù)字: ");
break;
}
} while (flag);
}
}
3.2 Data類
package cn.itcast;
/**
* 存放購物系統(tǒng)的初始化數(shù)據(jù)的數(shù)據(jù)類,該類只是存放了已有的商品信息和顧客信息
*
* @author
*
*/
public class Data {
/**
* 默認(rèn)構(gòu)造方法,初始化變量,由于都是數(shù)組對象或類對象,所以都需要采用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() ;
}
/**
* 初始化該類的數(shù)據(jù)
*
*/
public void initial() {
/*====================添加了初始的7種商品信息====================*/
goodsName [0] = "addidas運動鞋";
goodsPrice[0] = 880D;
goodsName [1] = "Kappa網(wǎng)球裙";
goodsPrice[1] = 200D;
goodsName [2] = "網(wǎng)球拍";
goodsPrice[2] = 780D;
goodsName [3] = "addidasT恤";
goodsPrice[3] = 420.77999999999997D;
goodsName [4] = "Nike運動鞋";
goodsPrice[4] = 900D;
goodsName [5] = "Kappa網(wǎng)球";
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 {
/**
* 設(shè)置默認(rèn)的用戶名和密碼
*
*/
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 {
/**
* 空構(gòu)造方法
*
*/
public VerifyEqual() {
}
/**
* 執(zhí)行驗證的方法
*
* @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 {
/**
* 空構(gòu)造方法
*
*/
public Menu() {
}
/**
* 設(shè)置菜單類中的數(shù)據(jù)信息
*
* @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購物管理系統(tǒng)1.0版\n\n");
System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
System.out.println("\t\t\t\t 1. 登 錄 系 統(tǒng)\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("請選擇,輸入數(shù)字:");
}
/**
* 顯示二級菜單,即系統(tǒng)的主菜單,這個方法里面包含了對這個菜單處理的所有流程
*
*/
public void showMainMenu() {
// 顯示二級菜單,即系統(tǒng)的主菜單
System.out.println("\n\n\t\t\t\t歡迎使用購物管理系統(tǒng)\n");
System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
System.out.println("\t\t\t\t 1. 客 戶 信 息 管 理\n");
System.out.println("\t\t\t\t 2. 購 物 結(jié) 算\n");
System.out.println("\t\t\t\t 3. 真 情 回 饋\n");
System.out.println("\t\t\t\t 4. 注 銷\n");
System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
// 用戶選擇服務(wù)項目
System.out.print("請選擇,輸入數(shù)字:");
Scanner scanner = new Scanner(System.in);
// 設(shè)置標(biāo)志用于控制循環(huán)
boolean flag = false;
do {
String s = scanner.next();
// 用戶選擇"客戶信息管理"
if (s.equals("1")) {
// 顯示客戶信息管理菜單并處理這個菜單的整個流程,當(dāng)這個流程處理完
showCustMMenu();
break;
}
// 用戶選擇"購物結(jié)算"
if (s.equals("2")) {
// 定義購物結(jié)算類的對象,并處理整個購物結(jié)算的流程
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("輸入錯誤,請重新輸入數(shù)字:");
flag = false;
} while (!flag);
}
/**
* 顯示三級菜單-客戶信息管理,并處理所有客戶信息管理的流程
*
*/
public void showCustMMenu() {
System.out.println("購物管理系統(tǒng) > 客戶信息管理\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("請選擇,輸入數(shù)字或按'n'返回上一級菜單:");
Scanner scanner = new Scanner(System.in);
boolean flag = true;
do {
// 創(chuàng)建客戶信息管理對象,并設(shè)置數(shù)據(jù),這里的數(shù)據(jù)還是原始的那些數(shù)據(jù)
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("輸入錯誤, 請重新輸入數(shù)字:");
flag = false;
} while (!flag);
}
/**
* 顯示三級菜單-真情回饋,并處理所有真情回饋的流程
*
*/
public void showSendGMenu() {
System.out.println("購物管理系統(tǒng) > 真情回饋\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("請選擇,輸入數(shù)字或按'n'返回上一級菜單:");
Scanner scanner = new Scanner(System.in);
// 創(chuàng)建禮物管理對象,并設(shè)置數(shù)據(jù),這里的數(shù)據(jù)還是原始的那些數(shù)據(jù)
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("輸入錯誤, 請重新輸入數(shù)字:");
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 {
/**
* 空構(gòu)造方法
*
*/
public CustManagement() {
}
/**
* 設(shè)置顧客信息管理類的數(shù)據(jù)信息
*
* @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("購物管理系統(tǒng) > 客戶信息管理 > 添加客戶信息\n\n");
Scanner scanner = new Scanner(System.in);
System.out.print("請輸入會員號(<4位整數(shù)>):");
int i = scanner.nextInt();
System.out.print("請輸入會員生日(月/日<用兩位數(shù)表示>):");
String s = scanner.next();
System.out.print("請輸入積分:");
int j = scanner.nextInt();
int k = -1;
int l = 0;
do {
if (l >= custNo.length)
break;
// 尋找數(shù)組中的第一個空位置,用來存儲新的顧客信息
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("購物管理系統(tǒng) > 客戶信息管理 > 修改客戶信息\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);
// 該會員存在,則進(jìn)行修改信息流程
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("請選擇,輸入數(shù)字:");
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("購物管理系統(tǒng) > 客戶信息管理 > 查詢客戶信息\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要繼續(xù)查詢嗎(y/n):");
}
// 返回上一級菜單
returnLastMenu();
}
/**
* 顯示所有客戶信息
*
*/
public void show() {
System.out.println("購物管理系統(tǒng) > 客戶信息管理 > 顯示客戶信息\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;
/**
* 處理顧客購買商品以及結(jié)算的類
*
* @author
*
*/
public class Pay {
/**
* 空構(gòu)造方法
*
*/
public Pay() {
}
/**
* 設(shè)置購物結(jié)算類的數(shù)據(jù)信息
*
* @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;
}
/**
* 根據(jù)會員信息確定折扣率
*
* @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;
}
/**
* 該類的關(guān)鍵方法,用于處理購物和結(jié)算
*
*/
public void calcPrice() {
String s2 = "";
double d1 = 0.0D;
double d2 = 0.0D;
int l = 0;
double d4 = 0;
System.out.println("購物管理系統(tǒng) > 購物結(jié)算\n\n");
System.out.println("*************************************");
System.out.println("請選擇購買的商品編號:");
// 顯示所有的可購買商品信息,這里的信息就是最初的那些初始化商品數(shù)據(jù)
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();
// 根據(jù)會員信息獲取打折信息
d4 = getDiscount(i, custNo, custScore);
String s1;
do {
System.out.print("\t請輸入商品編號:");
int j = scanner.nextInt();
System.out.print("\t請輸入數(shù)目:");
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是否繼續(xù)(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個數(shù)\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 {
/**
* 空構(gòu)造方法
*
*/
public GiftManagement() {
}
/**
* 設(shè)置禮物管理類的數(shù)據(jù)信息
*
* @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("購物管理系統(tǒng) > 生日問候\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();
}
/**
* 幸運抽獎,注意這里是隨機(jī)的抽獎,所以需要隨機(jī)數(shù),只需要自己制定一個抽獎規(guī)則就可以
*
*/
public void sendLuckyCust() {
System.out.println("購物管理系統(tǒng) > 幸運抽獎\n\n");
System.out.print("是否開始(y/n):");
Scanner scanner = new Scanner(System.in);
if (scanner.next().equals("y")) {
int i = (int) (Math.random() * 10D); // 產(chǎn)生一個隨機(jī)數(shù)
String s = "";
boolean flag = false;
for (int k = 0; k < custNo.length && custNo[k] != 0; k++) {
// 拿隨機(jī)數(shù)與顧客會員號的相應(yīng)結(jié)果進(jìn)行比較,從而判斷是否有顧客中獎
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("購物管理系統(tǒng) > 幸運大放送\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());
// 創(chuàng)建禮物類,并對禮物信息進(jìn)行設(shè)置,這里的禮物是固定的信息
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 {
/**
* 空構(gòu)造方法
*
*/
public Gift() {
}
/**
* 根據(jù)禮物對象的變量返回禮物的全部信息
*
*/
public String toString() {
return (new StringBuilder()).append("一個價值¥").append(price)
.append("的").append(name).toString();
}
/*====================定義該類所擁有的變量====================*/
public String name ; // 禮物名字
public double price; // 禮物價格
} 3.10 代碼總結(jié)
從上面的9個類的代碼來看,有一些需要注意的地方:
(1)在許多類中都定義了與Data中基本一樣的成員變量,只是沒有Manager對象而已,這是為了讓數(shù)據(jù)一層層保存和傳遞,通過setData()方法實現(xiàn),不過這種方法其實并不是很好,并且一般來說成員變量應(yīng)該最好設(shè)置為私有的,這里這樣的設(shè)計是為了操作方便,使系統(tǒng)更簡單一些,安全性不好。
(2)注意到所有要進(jìn)行字符串拼接的地方都使用JAVA中的StringBuilder類,這是為了高效處理字符串拼接,防止String類帶來的拼接數(shù)據(jù)冗余。
(3)這些設(shè)計中的流程并不是非常合理,大家可以自己的需要進(jìn)行修改。
(4)代碼中基本上沒有考慮異常時的處理,所以當(dāng)輸入時出現(xiàn)錯誤的時候,普通錯誤可以進(jìn)行重新輸入,但是如果出現(xiàn)不匹配等錯誤,直接會出現(xiàn)異常,從而退出系統(tǒng),這些也是本設(shè)計的缺陷,可以通過正則表達(dá)式等來完善一些。
總之,給出的代碼僅供參考,大家可以根據(jù)需要進(jìn)行修改,這些代碼都是經(jīng)過驗證的,可以直接運行。
4. 總結(jié)
這個設(shè)計只是為了說明一些基本的設(shè)計思想和設(shè)計理念,以及設(shè)計過程中需要考慮的問題,主要還是為了說明怎樣用面向?qū)ο蟮乃枷肴ソ鉀Q現(xiàn)實生活中的問題,所以設(shè)計相對簡單,不過希望大家可以通過這個設(shè)計理解這些基本的思想,從而幫助大家理想面向?qū)ο蟮幕舅枷搿?nbsp;
總之,語言只是一種解決問題的工具,大家可以用C++、C#等其他語言來實現(xiàn)這一系統(tǒng),只要有良好的設(shè)計理念和設(shè)計思想就可以。再次強(qiáng)調(diào),本設(shè)計僅供參考,歡迎大家參與討論,有錯誤的地方歡迎大家指正,謝謝。
相關(guān)文章
使用SpringBoot+Prometheus+Grafana實現(xiàn)可視化監(jiān)控
本文主要給大家介紹了如何使用Spring?actuator+監(jiān)控組件prometheus+數(shù)據(jù)可視化組件grafana來實現(xiàn)對Spring?Boot應(yīng)用的可視化監(jiān)控,文中有詳細(xì)的代碼供大家參考,具有一定的參考價值,需要的朋友可以參考下2024-02-02
CountDownLatch源碼解析之a(chǎn)wait()
這篇文章主要為大家詳細(xì)解析了CountDownLatch源碼之a(chǎn)wait方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-04-04
Springboot線程池并發(fā)處理數(shù)據(jù)優(yōu)化方式
這篇文章主要介紹了Springboot線程池并發(fā)處理數(shù)據(jù)優(yōu)化方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
mybatis的映射xml中動態(tài)設(shè)置orderby方式
springboot項目中mybatis-plus@Mapper注入失敗問題
詳解MyBatis?ResultSetHandler?結(jié)果集的解析過程
SpringBoot Security安裝配置及Thymeleaf整合

