java适合课设项目-实现快递E站
代码地址
环境:javaSE11,IDEA
实现功能:
初始版本
基于面向对象思想,自顶而下设计,我们依次定义以下的几个类
EStation
系统的顶层,EPackage类中依赖其他的几个类,带有方法run用以启动系统,系统会根据用户输入创建Manager类和用户User类,并将操作结果储存在MyList类中。同时,EStation提供生成不重复取件码和未被用到的快递位置的功能。
MyList
用数组的形式实现List的功能,在MyList中可以调用添加,删除,修改的方法。里面存储着快递类和快递在E站的位置
Manager
管理员类,在该类中,实现了管理员能操作的功能,包括将快递放入E站,修改快递信息,删除快递信息,遍历所有快递信息等方法。
User
用户类,只实现一个方法,根据输入的取件码取件。
EPackage
快递类,包括了快递编号,取件码,快递公司等属性
部分代码
public class EStation {
int positionNum = 5000;//快递初始位置有5000个
MyList myList = new MyList(positionNum);
boolean[] keyList = new boolean[1000000];//用来确保取件码之间不会发生碰撞
boolean[] positionList = new boolean[positionNum];//用来确保不重复快递位置
void run() {
Scanner input = new Scanner(System.in);
while(true) {
System.out.println("=====欢迎使用新职课快递柜====");
System.out.println("请输入您的身份:1-快递员;2-用户");
int user = input.nextInt();
switch(user){
case 1:
managerProcess(input);
break;
case 2:
userProcess(input);
break;
}
}
}
private void userProcess(Scanner input) {
User user = new User(input);
user.getIt(myList);
}
private void managerProcess(Scanner input) {
System.out.println("请选择操作:1-存快递 2-删除快递 3-修改快递信息 4-查看所有快递");
Manager manager = new Manager(input);
int choice = input.nextInt();
switch(choice){
case 1:
int key = genKey();
int position = genPosition();
manager.saveIt(myList,key,position);
break;
case 2:
int[] res2 = manager.deleteIt(myList);
//删除成功,把碰撞检测数组标记也清除
if (res2[0] != -1){
positionList[res2[0]] = false;
keyList[res2[1]] = false;
}
break;
case 3:
key = genKey();
int res3 = manager.writeIt(myList, key);
if (res3 != -1){
keyList[res3] = false;
}
break;
case 4:
manager.getAll(myList);
break;
}
}
int genKey(){
Random rand = new Random();
int key =0;
while(true){
key = rand.nextInt(900000)+100000;
if (!keyList[key]){
keyList[key] = true;
return key;
}
}
}
//生成快递位置
int genPosition(){
Random rand = new Random();
int number =0;
while(true){
number = rand.nextInt(positionNum)+1;
if (!positionList[number]){
positionList[number] = true;
return number;
}
}
}
}
做出来后自我感觉良好,但观摩了大佬做的后…觉得进步空间还挺大的。
初版代码只是实现了这样的功能,但从项目的设计上看,存在以下问题
- 用户输入并未做正确性验证
- 界面显示部分代码并没有和逻辑代码解耦,不同功能的代码混在一块
- 逻辑部分和数据存储部分未能实现高解耦
因此,在此基础上做了第二版进行改进
改进版本
从图中可以看到,首先添加了不同的包区分不同功能的类。其中,bean用以进行数据装载。main用以运行系统,实现项目运行的逻辑。root区分了不同的用户级别。views用来进行输入判断和界面显示。
- 当界面部分及用户输入部分需要修改时,只需要修改views包中的内容
- 当逻辑需要更改时,只需要去找Run里对应的部分
- 当需要添加新的用户人群时,在root中新建类便可
- 数据存储出现问题,只需要对bean中的类进行整改
自此,代码的结构和分工焕然一新
部分运行结果
改进版本2 -添加了序列化(gitee仓库的improve3)
将数据序列化储存到本地,从而下次可以从本地文件中直接读取过往数据,达到保存数据的作用
改进版本3 - 实现服务端和客户端(improve4)
通过socket实现了服务端和客户端通信,这个改进踩了很多坑,以前没有弄过通信这一块编程,费了不少时间
前置知识:Java的各种流,socket通信
- 为了确保前端后端能够同步运行,前端有个操作界面views,后端同样有个对应 的serlet
- 采用两次握手,即一端发送消息后,另一端收到后要回复收到,以此来使前后端逻辑同步(不丢包前提下)
- 构建前后端通信的序列化类,用对象流进行传输,这样可以避免多种流混用造成的奇怪问题,比如乱码
- 流对象开启后一整个线程都不要关闭,清空缓存用flush.