团队介绍
成员姓名 | 负责任务 |
---|---|
林洁颖 | 业务逻辑代码和类的设计 |
宋思坡 | gui设计、系统功能结构图 |
漆靖 | MVC模式编写、UML图设计、前期调查 |
庄昭和 | 博客书写、编码规范 |
git地址
https://gitee.com/zhuang-zhaohe/first/tree/master/购物车
系统功能流程图
UML图
前期调查
为了确定购物车系统的主要功能设计与之后的用户界面设计,我们浏览了了几个较为知名的购物APP,如京东、天猫、亚马逊等。
经过这些调查,我们观察到:
- 从商品的属性来看
所有商品都拥有名称、价格这两种属性。而细分下去,不同类型的商品又拥有各自独特的属性。如这本《梦之海》,它还拥有作者、出版社、ISBN编号等几样独特的属性:
(京东)
而这只吹风机,则还拥有额定功率、产品尺寸、产品颜色等独特的属性:
(京东)
- 从其实现的功能来看,
在主界面中,用户既可以通过关键词检索来寻找想要的商品,也可以在不同的分类中寻找商品:
(京东,搜索界面)
(京东,部分分类界面)
在商品界面中,这些APP都可以选择商品的款式与数量并加入购物车,
(京东)
在购物车界面,几家APP的购物车界面功能都大同小异,我们以京东为例,它的购物车界面首先向用户展示了购物车中的所有商品。其次,用户可以清空购物车、增加或减少某类商品的数量、移除某类商品。同时显示购物车中商品总价。
(京东)
- 从界面的角度来看,
在商品浏览界面,这几家购物APP的都采用网格式布局,并在一页内通过滚动条来浏览更多的商品,如下图,看上去简洁且一目了然,我们的界面设计或许可以参考一二。
(京东)
在商品详情界面,则一般会显示商品的详细信息(即各类属性),以及对商品的介绍等等。
在购物车界面,较为常见的布局方式是自上而下的布局,一行显示一类商品的简易信息以及总价,并在最底层显示所有商品的总价,而在最后的结算界面,通常还需要用户填写或选择配送地址。
(京东)
由于条件所限·,以上的调查都是从顾客的角度出发的。但我们不难推测,对于商家来说,他至少应当可以:
- 增加新的商品种类或减少已有的商品种类;
- 修改商品的库存以及包括价格、名称在内的各项属性和介绍等;
购物车中的MVC模式
MVC模式,即是指Model(模型)View(视图)Controler(控制器)。用图来说明的话,即如下图所示:
在我们的购物车项目中,这些类是“M”中的类,这些类则是“V”中的类。而MVC中的“C”,则以监听器的形式遍布在视图层的类中。
至于我们购物车项目中MVC模式的体现,我用下面这一段代码所实现的功能来说明:
当用户点击“结算”按钮时,位于该按钮上的Controler(即监听器)就会被触发,并通过modell与selecteRow从View(视图)中获取所需的信息。然后调用Model(模型)中的getQty与checkout方法得到number与allcheckout并将其返回给View(视图)。最后View更新显示的结果。
MVC模式的好处显而易见,即每一层内部的变化不影响其他层。每一层都对外提供接口(Interface),供上面一层调用。这样一来,软件就可以实现模块化,修改外观或者变更数据都不用修改其他层,也可以针对不同的层进行优化,提高效率。大大方便了维护和升级。
包管理
有三个包,dao包,model包,ui包。
1.dao包存放数据持久化类,Dao接口的实现类就放在dao包的iml子包下。
2.model包存放实体类,包含商品类。
3.ui包则包含视图界面,分别为登入界面LoginFrame类和注册界面RegisterDialog类和购物车主界面ShoppingcartFrame类。
复用问题
可以复用以前购物车代码,但会碰到很多问题,在刚开始设计购物车时考虑的方法在gui图形界面并不全都合适。例如遍历购物车时条目时源代码使用show的方式输出String类型的数据展示,且项目条是private类型的,在gui中使用table二维表格时更希望能的得到每一条项目条的对象,方便遍历展示每一个对象的各个数据(例如商品名,编码等)可视化呈现,还会有很多问题不一一列举了。
简述DAO模式
本项目中书写了ShoppingCartDao接口作为DAO模式的DAO接口,同时书写了ShoppingCartDao类和UserInformationDao类作为DAO接口的实现类。使用DAO模式的优势是可以将数据访问接口与数据访问实现相分离,可以极大地提高DAO接口的实现类的代码复用率,以及方便改变数据访问底层存储类型。
1、关键代码
-
LoginService类(功能:执行用户注册与登入类)
package model; /** * * @author Lenovo */ public class LoginService { public boolean loginService (String account, String password){ if(account.equals("") ||password.equals("")) return false; UserInformation u = new UserInformation(); // 判断是否注册过用户 if(u.findInformation(account, password)) { return true; } return false; } }
-
UserInformationDaoIml类(功能:注册用户信息文件操作接口的实现类)
package dao.iml; import dao.UserInformationDao; import java.io.*; /** * 注册用户信息文件操作接口的实现类 */ public class UserInformationDaoIml implements UserInformationDao { @Override public boolean registerInformation(String account, String password) { // User文件用来存用户账号密码 if(findInformation(account, password)) { return false; } File file = new File("User.txt"); FileWriter fw = null; BufferedWriter bw = null; String str = account + " " + password; try { fw = new FileWriter(file, true); bw = new BufferedWriter(fw); bw.write(str); bw.newLine(); bw.flush(); fw.flush(); bw.close(); fw.close(); } catch (IOException e) { return false; } return true; } /** * 判断该用户是否注册过,注册过返回true */ @Override public boolean findInformation(String account, String password) { File file = new File("User.txt"); Reader fr; try { fr = new FileReader(file); BufferedReader br = new BufferedReader(fr); String str = null; while((str = br.readLine()) != null) { String st[] = str.split(" "); if(account.equals(st[0]) && password.equals(st[1])) { br.close(); fr.close(); return true; } } br.close(); fr.close(); return false; } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } }
-
ShoppingCartDaoFileIml(功能:购物车类,实现对购物车的增删查改操作)
-
void changeFile()(对存储底层的文件信息修改)
/** * 购物车构造函数 * * @return */ public ShoppingCartDaoFileIml() { itemList = new ArrayList<ItemEntry>(); file = new File(pathname); //创建一个存储购物车信息的文件对象,默认文件路径在ShoppingCart.txt try (FileReader fr = new FileReader(pathname); BufferedReader bf = new BufferedReader(fr);) { //BufferedReader(FileReader("filename"))将FileReader包装后,再使用read(char[] chbf)读取,可以将文件内容装入缓存。 String str[]; String temp; while ((temp = bf.readLine()) != null) { //去除读入字符串的空格 str = temp.split("\s+"); String id = str[0]; String name = str[1]; double price = Double.valueOf(str[2]); String description = str[3]; int number = Integer.valueOf(str[4]); addItemEntry(new Commodity(id, name, price, description), number); } } catch (IOException e) { e.printStackTrace(); } }
-
ShoppingCartDaoFileIml()(通过读取文件信息对购物车的进行初始化)
/** * 对文件内容进行重写 * 将itemList的内容按行写入文件中 * * @throws Exception */ private void changeFile() { if (!file.isFile()) { try { file.createNewFile(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } BufferedWriter writer = null; try { writer = new BufferedWriter(new FileWriter(pathname)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } for (ItemEntry itemEntry : itemList) { try { writer.write(itemEntry + " "); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } try { writer.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
-