文章目录
在线上课程的购物车代码的基础上,改进与增加
一. 人员分工
任务 | 姓名 |
---|---|
Main类,ShoppingCenter类,MainFrame类,博客编写,UML图制作 | 黄羽悦 |
Commodity类,前期调查和功能设计,UML图制作 | 庄雨宸 |
Menu类,前期调查和功能设计,系统功能结构图 | 方雅婷 |
ShoppingCart类,编码规范设计,系统功能结构图 | 孙思雨 |
二. 前期调查
调查了京东的商城中的购物车,体验从搜索商品、加入购物车、操作购物车、下单全过程。
- 商城商品信息
2.购物车
三. 系统功能结构图
四. 部分功能运行结果展示:
1.商城内初始商品窗口显示
2.商品添加不允许重复
3.商品查询和删除功能
4.添加商品进购物车
5.计算商品总价,退出系统
五. 系统描述:
该系统是一个简单的购物车系统,用户可以选择添加商品、查看全部商品、查看指定编号的商品信息、删除商品、添加商品到购物车、显示购物车商品、删除购物车商品和计算购物车总价等操作。
名词: 商品,购物车;
动词:添加,查看,删除,计算,显示;
系统中存在以下对象:
- MainFrame:界面类,用于显示商品列表和与用户进行交互。
- ShoppingCenter:商店类,用于管理商品的增加、删除和查询。
- Commodity:商品类,包含商品的编号、名称和价格等属性。
- ShoppingCart:购物车类,用于管理购物车中的商品条目。
- ItemEntry:购物车条目类,包含商品和数量等属性。
系统的流程如下:
- 用户打开系统,界面显示商品列表。
- 用户可以选择添加商品、查看全部商品、查看指定编号的商品信息、删除商品、添加商品到购物车、显示购物车商品、删除购物车商品和计算购物车总价等操作。
- 添加商品:用户输入商品的编号、名称和价格,系统将商品添加到商店中。
- 查看全部商品:系统显示商店中所有的商品信息。
- 查看指定编号的商品信息:用户输入商品编号,系统根据编号查找商品信息并显示。
- 删除商品:用户输入商品编号,系统根据编号删除对应的商品。
- 添加商品到购物车:用户输入商品编号和数量,系统将商品添加到购物车中。
- 显示购物车商品:系统显示购物车中的所有商品信息。
- 删除购物车商品:用户输入商品删除对应商品使得数量减一
六. 类设计说明:类概述(有什么用)、类的属性与方法、类与类之间的关系。可选:类与类之间的关系可使用UML类图描述。建议使用ProcessOn绘制
对于购物车系统的类设计说明如下:
-
MainFrame
类(主界面类):- 概述:该类用于显示系统的主界面,提供用户与系统交互的入口。
- 属性:无
- 方法:添加商品按钮的事件处理方法、删除商品按钮的事件处理方法、查询商品按钮的事件处理方法、计算购物车总价的方法等。
textArea: JTextArea
:用于显示商品信息的文本区域。
displayCommodities(commodities: List<Commodity>): void
:用于在主窗体中显示商品信息的方法。 - 关系:与 ShoppingCenter 类和 ShoppingCart 类有关联关系。
-
ShoppingCenter
类(商店类):- 概述:该类用于管理商品的信息和提供商品列表。
- 属性:商品列表(commodityList)
commodityList: List<Commodity>
:存储所有商品的列表。 - 方法:获取商品列表的方法、根据商品名称查询商品的方法等。
add(commodity: Commodity): void
:添加商品到商品列表的方法。
displayAll(): void
:显示所有商品的方法。
findAll(): List<Commodity>
:返回所有商品列表的方法。
findId(id: int): Commodity
:根据商品ID查找并返回对应商品的方法。
removeId(id: int): void
:根据商品ID将对应商品从商品列表中移除的方法。 - 关系:与 MainFrame 类和 Commodity 类有关联关系。
-
Commodity
类(商品类):- 概述:该类用于表示商品的信息。
- 属性:名称,编号,价格
id: Integer
:商品的唯一编号。
name: String
:商品的名称。
price: Double
:商品的价格。 - 方法:获取商品名称的方法、获取商品价格的方法等。
Commodity()
:无参构造函数。
Commodity(id: Integer, name: String, price: Double)
:带参构造函数。
getId(): Integer
:获取商品ID的方法。
setId(id: Integer): void
:设置商品ID的方法。
getName(): String
:获取商品名称的方法。
setName(name: String): void
:设置商品名称的方法。
getPrice(): Double
:获取商品价格的方法。
setPrice(price: Double): void
:设置商品价格的方法。
hashCode(): int
:计算商品对象的哈希码。
equals(obj: Object): boolean
:判断商品对象是否相等。
toString(): String
:将商品对象转换为字符串表示。 - 关系:与 ShoppingCenter 类有关联关系。
-
ShoppingCart
类(购物车类):- 概述:该类用于管理购物车的内容和计算购物车总价。
- 属性:购物车列表。
itemList: List<ItemEntry>
:存储购物车中的商品条目列表。 - 方法:添加商品到购物车的方法、从购物车中删除商品的方法、计算购物车总价的方法等。
itemList: List<ItemEntry>
:存储购物车中的商品条目列表。
calculate(): String
:计算购物车中所有商品的总价格。
add(commodity: Commodity, quantity: int): void
:向购物车中添加指定数量的商品条目。
remove(id: Integer): boolean
:从购物车中移除指定ID的商品条目。
displayAll(): void
:显示购物车中所有商品的信息。
findById(id: Integer): int
:根据商品ID在购物车中查找并返回商品条目的索引。 - 关系:与 MainFrame 类和 Commodity 类有关联关系。
-
Menu
:菜单类:- 概述:显示菜单。
- 方法:
show(): void
:显示菜单选项的方法。
-
Main
:程序的入口类:- 概述:程序的入口。
- 方法:
main
方法。
main(String[] args): void
:主方法,用于启动程序,接收用户输入并调用相应的方法。
MainFrame
类与ShoppingCenter
类之间存在依赖关系,通过displayCommodities
方法从ShoppingCenter
获取商品列表并显示到窗体上。ShoppingCart
类与ShoppingCenter
类之间可能存在关联关系,通过购物车中的商品条目的商品ID,调用ShoppingCenter
的方法查找对应的商品信息。ShoppingCart
类与MainFrame
类之间可能存在依赖关系,通过displayAll
方法从购物车中获取商品信息并显示到窗体上。Main
类与上述所有类都有交互和调用关系,作为整个程序的入口点和控制中心。
以下是类之间关系的 UML 类图描述:
六. 本系统哪里体现了面向对象的封装性?可选:哪里体现了继承与多态?
本系统体现了面向对象的封装性的地方在于类的设计和属性与方法的封装。每个类都有自己的属性和方法,通过封装可以隐藏类的内部实现细节,只暴露对外部可见的接口,提高了代码的可维护性和可扩展性。
在购物车系统中,类的封装性可以通过以下几个方面来体现:
- 类的属性被定义为私有(private),只能通过类的方法进行访问和修改,防止外部直接访问和修改属性。
- 类的方法可以对属性进行合理的操作和控制,保证数据的有效性和一致性。
- 类的方法可以提供对外的接口,供其他类进行调用,而不需要了解类的内部实现细节。
继承与多态在购物车系统中并不是必需的,因为购物车系统的功能相对简单,没有明显的继承关系和多态性质的需求。但如果系统需要扩展,例如添加新的商品类别,可以考虑使用继承和多态来实现更灵活的功能。
七. 项目包结构(package的划分)与关键代码:项目的包结构(为什么要这样设计包结构),主要功能(如网购物车添加、删除商品)的流程图与关键代码
项目包结构的设计是为了提高代码的可维护性和可扩展性。一种常见的包结构设计是按照功能或模块进行划分,每个包代表一个模块或功能,包内包含相关的类和接口。
主要功能的流程图:
- 购物车添加商品的流程图:
开始 -> 显示商品列表 -> 选择商品 -> 添加到购物车 -> 显示购物车内容 -> 结束
- 关键代码:
- 购物车类
package shopping;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class ShoppingCart {
private static List<ItemEntry> itemList = new ArrayList<>();//
// 计算购物车内商品总价
public String calculate() {
BigDecimal sum = new BigDecimal("0");
for (ItemEntry itemEntry : itemList) {
BigDecimal priceCal = new BigDecimal(Double.toString(itemEntry.item.getPrice()));
BigDecimal qtyCal = new BigDecimal(itemEntry.qty.toString());
sum = sum.add(priceCal.multiply(qtyCal));
}
return sum.toString();
}
// 增加商品
public void add(Commodity e, int sum) {
if (e == null) {
return;
}
int index = findById(e.getId());
if (index == -1) {// 如果不包含该商品的条目
itemList.add(new ItemEntry(e, sum));
} else {
System.out.println("商品已经存在购物车,数量增加");
itemList.get(index).increase(sum);
}
}
// 减少商品数量
public boolean remove(Integer id) {
if (id == null)
return false;
int index = findById(id);
if (index == -1) { // 未找到
return false;
} else {
ItemEntry entry = itemList.get(index);
if (entry.getQty() <= 1) {// 当条目数量<1则删除条目
itemList.remove(index);
} else {
entry.decrease();
}
}
return true;
}
// 展示购物车内的商品
public void diplayAll() {
for (ItemEntry itemEntry : itemList) {
System.out.println(itemEntry);
}
}
// 通过id在购物车中查找是否已存在相关条目。 声明为private,因为只在本类中使用。 如果包含返回相关条目所在下标,否则返回-1
private int findById(Integer id) {
for (int i = 0; i < itemList.size(); i++) {
if (itemList.get(i).getItem().getId().equals(id))
return i;
}
return -1;
}
// 购物车条目类:代表购物车的某一个条目,包含商品与商品对应的数量。该类为内部类。
private class ItemEntry {
Commodity item;// 商品
Integer qty;// 数量
public ItemEntry(Commodity item, int sum) {
this.item = item;
qty = sum;
}
public void increase(int sum) {
qty += sum;
}
public void decrease() {
qty--;
}
public Commodity getItem() {
return item;
}
public Integer getQty() {
return qty;
}
@Override
public String toString() {
return "条目:" + item + ", 商品数量=" + qty;
}
}
}
- 商城类
package shopping;
import java.util.ArrayList;
import java.util.List;
public class ShoppingCenter {
private static List<Commodity> commodityList = new ArrayList<Commodity>();
// static 静态代码块,第一次加载的时候执行,只执行一次,静态变量进行初始化
static {
commodityList.add(new Commodity(1000, "手机", 2999.9));
commodityList.add(new Commodity(1001, "电脑", 12999.9));
commodityList.add(new Commodity(1002, "充电器", 9.9));
commodityList.add(new Commodity(1003, "牛奶", 59.9));
}
public void add(Commodity co) {
boolean flag = false;
for (int i = 0; i < commodityList.size(); i++) {
Commodity commodity = commodityList.get(i);
if (co.getId().equals(commodity.getId())) {
flag = true;
break;
}
}
if (flag) {
System.out.println("商品已经存在");
} else {
System.out.println("添加成功");
commodityList.add(co);
}
}
public void diplayAll() {
for (Commodity commodity : commodityList) {
System.out.println(commodity);
}
}
public List<Commodity> findAll() {
return commodityList;
}
public Commodity findId(int id) {
// 比较查找编号
for (int i = 0; i < commodityList.size(); i++) {
Commodity commodity = commodityList.get(i);
if (commodity.getId() == id) {
return commodity;
}
}
return null;
}
public void removeId(int id) {
boolean flag = false;
for (int i = 0; i < commodityList.size(); i++) {
Commodity commodity = commodityList.get(i);
if (commodity.getId() == id) {
commodityList.remove(commodity);
flag = true;
}
}
if (flag) {
System.out.println("删除成功");
} else {
System.out.println("没有该商品");
}
}
}
八. 系统优化总结
系统主要优化了以下功能:
- 改进ShoppingCart类中的add方法,将相同商品归为一类。
- 为Commodity类添加编号属性,用来唯一区别每一个不同的商品,确保商品编号唯一性。
- 增加专门的菜单类,用来显示菜单。
- 增加专门的类用来进行Commodity数据的初始化。
- 将ShoppingCart类的控制台输出代码(System.out.println…)全部移除。
- Commodity类的price为double类型不精确。在运算过程中会出现误差。使用BigDecimal类:BigDecimal类提供了高精度的十进制运算,避免浮点数运算的精度问题,使得运算结果精确。
- 在开始增加窗口显示商城商品。
- 利用购物车条目存储商品信息。
- 解决同一商品多次存储问题,在增加商品进入购物车时可以选择数量。