一、人员分工
任务 | 姓名 |
---|---|
Main类、Menu类、博客编写、UML图制作 | 丁升高 |
Commodity类、前期调查和功能设计 | 姚远 |
Mall类、编码规范设计、系统功能结构图 | 徐维辉 |
ShoppingCart类、前期调查和功能设计、编码规范设计 | 邱良厦 |
本购物车系统在线上课程的购物车代码的基础上进行改进和补充。
二、前期调查
调查了京东商城和亚马逊商城中的购物车,体验从搜索商品、加入购物车、操作购物车、下单的全过程。
- 商品信息。
- 商品编号
- 操作购物车
三、系统功能结构图
四、系统描述
该系统是一个比较简单的购物车系统,使用者可以作为商城管理员体验添加商品到商城(包括商品初始化)、删除商城中的商品(指定编号或商品名或种类)、修改商城中的商品、查找商品。使用者也可以作为用户浏览商城中的商品、将商品添加到购物车、清除购物车中的某件商品、修改购物车中某商品的数量、清空购物车,购物车还能够自动统计商品种类数量以及计算商品总价。
名词:商城、商品、购物车。
动词:添加、删除、修改、查找、浏览、清除、清空、计算。
五、运行结果展示
1.显示全部商品。
2.添加商品到商城。
3.添加到商城的编号不能重复,保证商品编号的唯一性。
4.删除指定编号的商品(若商城没有该编号则删除失败)
5.修改某编号的商品(修改后的编号也不能于已有的商品重复)
6.按照商品名、商品种类、商品编号查找(忽略字母大小)。
7.添加到购物车(通过编号添加,且需要正确的编号)。
8.打开我的购物车。
9.修改商品数量(也可以通过商城再次添加到购物车)。
10.删除购物车内指定商品。
11.清空购物车。
六、类设计说明:类概述(有什么用)、类的属性与方法、类与类之间的关系。可选:类与类之间的关系可使用UML类图描述。建议使用ProcessOn绘制。
-
Main
类(程序入口类):-
概述:程序的入口。
-
方法:
main
方法。mallFunction(int choice, Scanner sc, Mall mall, ShoppingCart shoppingcart): boolean
:调用商城具有的相关的方法。
shoppigCartFunction(ShoppingCart shoppingcart, Scanner sc): void
:调用购物车具有的相关方法。
整个系统的主方法,负责调用商城类,接收用户的输入,同时也创建各个类的对象。
-
-
Menu
类(菜单、主操作类):-
概述:显示用户可以使用的相关操作,负责类与类之间的调用。
-
方法:
Menu()
:无参构造器。showMall(): void
:展示商城类中具有的相关操作。showshowShoppigCart(): void
:自动显示购物车中的商品,展示购物车具有的相关操作。
-
-
Commodity
类(商品类):-
概述:用于表示某个商品。
-
属性:
name:String
:商品名。price:double
:商品价格。number:int
:商品在购物车中的数量。id:int
:商品编号。categoryName:String
:商品类别。 -
方法:
Commodity()
:无参构造器。getName():String
:获取商品名。getPrice():double
:获取商品价格。getNumber():int
:获取商品在购物车中的数量。getId():int
:获取商品的编号。getCategoryName():String
:获取商品的类别。setName(String name):void
:设置商品名。setPrice(double price):void
:设置商品价格。setNumber(int number):void
:设置商品在购物车中的数量。setId(int id):void
:设置商品编号。setCategoryName(String categoryName):void
:设置商品类别。addNumber():void
:添加到购物车时使购物车里的商品数量+1。toString():String
:将商品对象转化为字符串。equals(Object obj):boolean
:比较两个商品是否相等。
-
-
Mall
类(商城类):-
概述:用于管理商城。
-
属性:
mallList:List<Commodity>
:存储商城类中的商品列表。 -
方法:
Mall()
:无参构造器。getMallList():List<Commodity>
:获取所有商品。addForMall(String name, double price, int id, String categoryName):boolean
:添加商品到商城。addForShoppingCar(ShoppingCart car, int id):boolean
:将商品添加到购物车。removeCommodityOfId(int id):boolean
:删除指定编号的商品。removeCommodityOfname(String name):boolean
:删除某商品。modifyCommodity(int id1, String name, double price, int id2, String categoryName):boolean
:修改指定商品。searchCommodityOfId(int id):int
:按照商品编号搜索商品。searchCommodityOfName(String name):List<Commodity>
:按照商品名搜索商品。searchCommodityOfCategoryName(String categoryname):List<Commodity>
:按照商品类别搜索商品。
-
-
ShoppingCart
类(购物车类):-
概述:用于管理购物车。
-
属性:
items:List<Commodity>
:存储购物车商品列表。 -
方法:
ShoppingCart()
:无参构造器。getItems():List<Commodity>
:获取购物车内所有商品。add(Commodity item):void
:结合addForShoppingCar
将商品添加到购物车。getQty():int
:获取购物车商品种类的数量。checkout():double
:计算购物车内商品的总价。modifyNumber(int number, int id):boolean
:修改购物车内商品的数量。clear():void
:清空购物车。remove(int id):boolean
:删除指定编号的商品。searchCommodityOfId(int id):int
:查找指定编号的商品。
-
Main
类与Mall
类和ShoppingCart
类存在依赖关系,Mall
类和ShoppingCart
类中的大部分方法依赖Main
类的调用,同时Menu
类也是Mall
类和ShoppingCart
类之间的桥梁,商品从商城添加到购物车就依赖Main
类。Main
类创建了商城对象和购物车对象,通过调用Menu
类带动整个程序。Menu
类展示商城和购物车相关操作。
类与类之间的UML关系图如下:
七、本系统哪里体现了面向对象的封装性?可选:哪里体现了继承与多态?
本系统在类中的属性和方法中体现了面向对象的封装性。每个类都有自己的属性和方法,将属性私有化通过提供公开的方法来访问和修改相关属性隐藏了类内部的具体实现,提高了代码的可维护性。
本系统功能相对简单暂时没有使用继承和多态,当添加更多的类使某些类更加具体时可以使用继承于多态。
八、项目包结构(package的划分)与关键代码:项目的包结构(为什么要这样设计包结构),主要功能(如网购物车添加、删除商品)的流程图与关键代码。
项目包结构为:
项目包结构这样设计是为了提高代码的可读性和可维护性。
主要功能流程图:
关键代码:
- 商城类
package shopping;
import java.util.ArrayList;
import java.util.List;
/**
* 商城类:用来存放一系列商品。
* 默认商城中商品数量很多
*/
public class Mall {
private List<Commodity> mallList = new ArrayList<>();
public Mall() {
}
/**
*
* @return 一个ArrayList,表示商品列表。
*/
public List<Commodity> getMallList() {
return mallList;
}
/**
* 先将商品初始化再将商品添加到商城中。
*/
public boolean addForMall(String name, double price, int id, String categoryName) {
Commodity commodity=new Commodity();
commodity.setName(name);
commodity.setPrice(price);
commodity.setId(id);
commodity.setCategoryName(categoryName);
int flag=searchCommodityOfId(id);
if(flag<0) {//找不到才能添加
this.mallList.add(commodity);
return true;
}
return false;
}
/**
*选择是否添加到购物车
*/
public boolean addForShoppingCar(ShoppingCart car, int id) {
int index=searchCommodityOfId(id);
if(index<0)return false;
else {
car.add(mallList.get(index));
return true;
}
}
/**
* 删除指定编号的商品
*/
public boolean removeCommodityOfId(int id) {
if(mallList.size()==0)return false;
boolean flag=false;
for(Commodity commodity : mallList) {
if(commodity.getId()==id) {
mallList.remove(commodity);
flag=true;
break;
}
}
return flag;
}
/**
* 删除某件商品
*/
public boolean removeCommodityOfname(String name) {
if(mallList.size()==0)return false;
boolean flag=false;
for(Commodity commodity : mallList) {
if(commodity.getName().equals(name)) {
mallList.remove(commodity);
flag=true;
break;
}
}
return flag;
}
/**
* 修改成功返回true否则返回false
*/
public boolean modifyCommodity(int id1, String name, double price, int id2, String categoryName) {
int temp=searchCommodityOfId(id1);
int temp1=searchCommodityOfId(id2);//修改后编号不能和商城中的其他商品重复
if(temp1>=0)return false;
if(temp>=0) {
mallList.get(temp).setName(name);
mallList.get(temp).setPrice(price);
mallList.get(temp).setId(id2);
mallList.get(temp).setCategoryName(categoryName);
return true;
}
return false;
}
/**
* 查找指定编号的商品
* @param id 待查找商品编号
* @return 若>=0则查找成功否则查找失败
*/
public int searchCommodityOfId(int id) {
int index=-1;
for(int i=0;i<mallList.size();i++) {
if(mallList.get(i).getId()==id) {
index=i;
break;
}
}
return index;
}
/**
* 查找相关商品。
* @param name 待查找的商品名
* @return 一个List表示所有查找到的商品
*/
public List<Commodity> searchCommodityOfName(String name){
List<Commodity> items = new ArrayList<>();
for(Commodity temp : mallList) {
if(temp.getName().equalsIgnoreCase(name)) {
items.add(temp);
}
}
return items;
}
/**
* 查找相关商品。
* @param name 待查找的种类名
* @return 一个List表示所有查找到的商品
*/
public List<Commodity> searchCommodityOfCategoryName(String categoryname){
List<Commodity> items = new ArrayList<>();
for(Commodity temp : mallList) {
if(temp.getCategoryName().equalsIgnoreCase(categoryname)) {
items.add(temp);
}
}
return items;
}
}
- 购物车类
package shopping;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* 购物车类:可以用来存放商品,且包含购物车常用的操作方法。
*/
public class ShoppingCart {
private List<Commodity> items = new ArrayList<>();//存放商品的容器
public ShoppingCart() {
}
public List<Commodity> getItems() {
return items;
}
/**
* 添加某件商品到购物车
*/
public void add(Commodity item) {
int id = items.indexOf(item);
if (id == -1) {
items.add(item);
item.setNumber(1);
} else {
items.get(id).addNumber();
}
}
/**
* 获得购物车内商品(种类)的数量
* @return 购物车内商品的数量
*/
public int getQty() {
return items.size();
}
/**
* 结算
* @return 返回购物车中所有商品的总价
*/
public double checkout() {
double x = 0;
for (Commodity commodity : items) {
BigDecimal a=new BigDecimal(commodity.getPrice());//有点占内存
BigDecimal b=new BigDecimal(commodity.getNumber());
x += a.multiply(b).doubleValue();
}
return x;
}
/**
* 修改某件商品的数量
*/
public boolean modifyNumber(int number, int id) {
int index=searchCommodityOfId(id);
if(index<0)return false;//编号错误
if(number<=0)return false;//数量错误
else {
items.get(index).setNumber(number);
return true;
}
}
/**
* 清空购物车
*/
public void clear() {
items.clear();
}
/**
* 删除某件商品(指定编号),相当于选中某商品
*/
public boolean remove(int id) {
int index=searchCommodityOfId(id);
if(index>=0) {
items.remove(items.get(index));
return true;
}
return false;
}
/**
* 查找指定编号的商品
* @param id 待查找商品编号
* @return 若>=0则查找成功否则查找失败
*/
public int searchCommodityOfId(int id) {
int index=-1;
for(int i=0;i<items.size();i++) {
if(items.get(i).getId()==id) {
index=i;
break;
}
}
return index;
}
}
- 商品类
package shopping;
/**
* 商品类:用来存放商品的信息(商品名称name、商品价格price、商品编号id、商品种类categoryName)。
*/
public class Commodity {
private String name;
private double price;
private int number=0;//某件商品在购物车中的数量
//private int numberInMall;//某件商品在商城中的数量
private int id;//商品编号
private String categoryName;//商品类别
public Commodity() {
}
// public Commodity(String name, double price) {
// this.name = name;
// this.price = price;
// }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public void setNumber(int number) {
this.number=number;
}
public int getNumber(){
return this.number;
}
public void setId(int id) {
this.id=id;
}
public int getId() {
return this.id;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public void addNumber() {
this.number+=1;
}
public String toString() {
return "商品编号:"+this.id+"\t商品名:"+this.name+"\t商品价格:"+this.price+"\t商品种类:"+this.categoryName;
}
public boolean equals(Object obj) {
if(obj==null)return false;
if(this==obj)return true;
if(obj instanceof Commodity) {
Commodity o1=(Commodity)obj;
if(this.name==null && o1.name==null)return this.price==o1.price;
else {
if(this.name==null || o1.name==null)return false;
return this.name.equals(o1.name)&&this.price==this.price;
}
}else {
return false;
}
}
}
- Menu类
package ui;
/**
* 菜单类:提供给用户选择相应操作。
*
*/
public class Menu {
public Menu() {
}
public void showMall() {
System.out.println("***********欢迎进入JMU-Mall***********");
System.out.println(" 1. 添加商品到商城");
System.out.println(" 2. 删除商品");
System.out.println(" 3. 修改商品");
System.out.println(" 4. 查找商品");
System.out.println(" 5. 显示全部商品");
System.out.println(" 6. 添加到我的购物车");
System.out.println(" 7. 打开我的购物车");
System.out.println(" 0. 退出");
System.out.println("*************************************");
}
public void showShoppingCart() {
System.out.println("***********你可以进行如下操作**********");
System.out.println(" 1. 修改商品数量");
System.out.println(" 2. 删除指定商品");
System.out.println(" 3. 清空购物车");
System.out.println(" 0. 退出");
System.out.println("*************************************");
}
}
- Main类
package ui;
import shopping.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Mall mall = new Mall();
ShoppingCart shoppingcart=new ShoppingCart();
Menu menu=new Menu();
Scanner sc = new Scanner(System.in);
mall.addForMall("苹果", 10.5, 1005, "水果");
mall.addForMall("手机", 1025.99, 1004, "电子产品");
mall.addForMall("Java教程", 8.88, 1003, "书籍");
//mall.addForMall("西瓜", 25.8, 1007, "水果");
mall.addForMall("香蕉", 16.8, 1002, "水果");
boolean runing=true;
while(runing) {
menu.showMall();
int choice=sc.nextInt();
runing=mallFunction(choice,sc,mall,shoppingcart,menu);
}
System.out.println("欢迎下次光临");
}
public static boolean mallFunction(int choice, Scanner sc, Mall mall, ShoppingCart shoppingcart,Menu menu) {
boolean runing=true;
String name;
double price;
int id;
int id1;
String categoryName;
boolean temp;//判断操作是否成功
List<Commodity> malllist=new ArrayList<>();
int flag;//case 4中使用
switch (choice) {
case 1:
System.out.println("请输入商品的名称:");
name=sc.next();
System.out.println("请输入商品的价格:");
price=sc.nextDouble();
System.out.println("请输入商品的编号:");
id=sc.nextInt();
System.out.println("请输入商品的种类:");
categoryName=sc.next();
temp=mall.addForMall(name, price, id, categoryName);
if(temp)System.out.println("添加成功");
else System.out.println("添加失败(商品重复添加)");
//System.out.println("");
//System.out.println("");
break;
case 2:
System.out.println("请输入你要删除的商品编号:");
id=sc.nextInt();
temp=mall.removeCommodityOfId(id);
if(temp)System.out.println("删除成功");
else System.out.println("删除失败(请输入正确的编号)");
break;
case 3:
System.out.println("请输入你要修改的商品编号:");
id=sc.nextInt();
System.out.println("请输入新的商品名称:");
name=sc.next();
System.out.println("请输入新的商品价格:");
price=sc.nextDouble();
System.out.println("请输入新的商品编号:");
id1=sc.nextInt();
System.out.println("请输入新的商品种类:");
categoryName=sc.next();
temp=mall.modifyCommodity(id, name, price, id1, categoryName);
if(temp)System.out.println("修改成功");
else System.out.println("修改失败(请输入正确的商品编号或检查新的编号是否重复)");
break;
case 4:
System.out.println("请选择查询方式:1.商品名 2.商品种类 3.商品编号");
flag=sc.nextInt();
if(flag==1) {
System.out.println("请输入商品名:");
name=sc.next();
malllist=mall.searchCommodityOfName(name);
if(malllist.size()==0)System.out.println("无法查询到该商品");
for(Commodity commodity : malllist) {
System.out.println(commodity);
}
}else if(flag==2) {
System.out.println("请输入商品种类:");
categoryName=sc.next();
malllist=mall.searchCommodityOfCategoryName(categoryName);
if(malllist.size()==0)System.out.println("无法查询到相关商品");
for(Commodity commodity : malllist) {
System.out.println(commodity);
}
}else if(flag==3) {
System.out.println("请输入商品编号:");
id=sc.nextInt();
int temp1=mall.searchCommodityOfId(id);
if(temp1<0)System.out.println("未查找到该商品");
else System.out.println(mall.getMallList().get(temp1));
}else {
System.out.println("输入错误自动返回");
}
break;
case 5:
malllist=mall.getMallList();
if(malllist.size()==0)System.out.println("商城为空");
for(Commodity commodity : malllist) {
System.out.println(commodity);
}
break;
case 6:
System.out.println("请输入你要添加到购物车的商品的编号:");
id=sc.nextInt();
int temp1=mall.searchCommodityOfId(id);
if(temp1>=0) {
shoppingcart.add(mall.getMallList().get(temp1));
System.out.println("添加成功");
}else {
System.out.println("添加失败(请输入正确的编号)");
}
break;
case 7:
shoppingCartFunction(shoppingcart, sc, menu);
break;
default:
runing=false;
break;
}
return runing;
}
public static void shoppingCartFunction(ShoppingCart shoppingcart, Scanner sc, Menu menu) {
int choice;
int id;
int number;
boolean temp;
boolean runing=true;
List<Commodity> items=shoppingcart.getItems();
if(items.size()==0) {
System.out.println("你的购物车为空(自动返回商城)");
return;
}else {
System.out.println("你的购物车有商品如下:");
for(Commodity commodity : items) {
System.out.println(commodity+"\t商品数量:"+commodity.getNumber());
}
System.out.println("购物车商品种类数量:"+shoppingcart.getQty());
System.out.print("所有商品总价:");
System.out.printf("%.2f",shoppingcart.checkout());
System.out.println();
}
menu.showShoppingCart();
choice=sc.nextInt();
switch (choice) {
case 1:
System.out.println("请输入你要修改的商品的编号:");
id=sc.nextInt();
System.out.println("请输入你要修改的商品的数量:(数量必须大于等于1)");
number=sc.nextInt();
temp=shoppingcart.modifyNumber(number, id);
if(temp) {
System.out.println("修改成功");
}else {
System.out.println("修改失败(请检查商品编号或商品数量是否符号规范)");
}
break;
case 2:
System.out.println("请输入你要删除的商品的编号");
id=sc.nextInt();
temp=shoppingcart.remove(id);
if(temp) {
System.out.println("删除成功");
}else {
System.out.println("删除失败");
}
break;
case 3:
shoppingcart.clear();
break;
default:
runing=false;
break;
}
if(runing)shoppingCartFunction(shoppingcart, sc, menu);
else return;
}
}
九、系统功能优化总结
- 改进了ShoppingCart类中的add方法,将相同商品归为一类。
- 为ShoppingCart增加了搜索功能。
- 为Commodity类添加编号属性,用来唯一区别每一个不同的商品。
- 增加专门的菜单类,用来显示菜单。
- 增加专门的类用来进行Commodity数据的初始化。
- 将ShoppingCart类的控制台输出代码(System.out.println…)全部移除。
- Commodity类的price为double类型不精确,在运算过程中会出现误差。使用BigDecimal类计算商品总价,提高了运算结果的准确性。
- 为商品增加了类别属性,同时提供了多种搜索方式。