前言
通过这个小项目,加深入了我Java面向对象的理解,树立了编程重视逻辑的认知,以及对细节的处理能力,对需求的实现能力,以下是我对这个小项目的理解:
~还有很多前端页面没有写,也没有连接数据库就当作是个半成品吧
.这是跟着老韩做的有没有小伙伴也跟着写过呢哈哈哈
一.需求
实现基于文本界面的房屋出租软件。
能够实现对房屋信息的添加、修改和删除(用数组实现),并能够打印房屋明细表
展示一个草草写的前端页面:(有点丑哈哈哈)
二.分层设计
**1.编写House类用于存放属性
2.编写HouseView类用于显示
3.编写HouseService用于实现功能
4.编写HouseShow用于在主方法中调用方法实现用户操作**
通过多个类之间属性,方法的调用实现功能的交互,每个类各司其职,条理更加清晰
三.具体功能
==操作的细节都写在代码块的注释里了噢==
房源属性设置:
public class House {
//编号 房主 电话 地址 月租 状态(未出租/已出租)
int id;
private String name;
private String phone;
private String address;
private int rent;
private String state;
public House(int id, String name, String phone, String address, int rent, String state) {
this.id = id;
this.name = name;
this.phone = phone;
this.address = address;
this.rent = rent;
this.state = state;
}
//这里用于封装的get,set 方法省略了....
//为了方便的输出对象信息,我们实现toString
public String toString(){
return id+"\t"+name+"\t"+phone+"\t"+address+"\t\t"+rent+"\t\t"+state;
}
}
初始化业务层对象HouseService,引入工具包Utility
import yu7.daily.houserent.utility.Utility;
/**
* //定义House[],保存House对象
* //1.响应HouseView的调用
* //2.完成对房屋信息的各种操作(增删改查lc[create]r[read]u[update]d[delete])
*/
public class HouseService {
private House[] houses; //保存House对象
private int houseNum = 1;
private int idCounter = 1; //记录房屋个数
//带参构造器
public HouseService(int size) {
houses = new House[size]; //当创建HouseService对象,指定数组大小
//为了配合测试,这里初始化一个对象
houses[0] = new House(1, "mike", "18995895873", "xxxxx", 2000, "未出租");
}
引入显示层必要属性:
private boolean loop = true; //控制do-while语句
private String key;//控制switch语句
private HouseService houseService = new HouseService(10); //创建设置数组大小为10
1.显示主菜单功能
显示层:
//主菜单
public void mainMenu() {
do {
System.out.println("=========房屋出租系统===========");
System.out.println("\t1 查 找 房 源");
System.out.println("\t2 新 增 房 源");
System.out.println("\t3 删 除 房 屋 信 息");
System.out.println("\t4 修 改 房 屋 信 息");
System.out.println("\t5 房 屋 列 表");
System.out.println("\t6 退 出");
System.out.println("\t请输入1-6");
key = Utility.readString(1); //调用的是Utility里的静态方法 不用实例化直接用!
switch (key) { //开关控制 处理输入的key
case "1":
findHouse(); //查找房源
break;
case "2":
addHouse(); //增添房源
break;
case "3":
delHouse(); //删除房源
break;
case "4":
update(); //修改房源
break;
case "5":
listHouse(); //显示房源
break;
case "6":
backOf(); //退出
loop = false; //退出循环啦
break;
}
} while (loop); //退出do-while的条件loop=false
}
用户只需要在主函数调用此方法就可体验所有功能
2.查找房源功能
显示层:
//查找房屋操作
public void findHouse() {
System.out.println("================查找房屋信息==============");
System.out.println("请输入查找id:");
int findId = Utility.readInt();
House house = houseService.findByid(findId); //实例化的对象house指向地址!!
//findByid方法的返回类型是House 这里我要创建一个House对象来调用对应的方法
// 体现了"类型一致性原则!"
if (house != null) {
System.out.println(house);
//如果地址不为空 那我就输出那个地址,也就是houseService.findByid(findId)中对应的house[i]
} else {
System.out.println("对不起没找到~~~");
}
}
业务层:
//查找房屋id
public House findByid(int findId){
for (int i = 0; i < houseNum; i++) { //遍历数组
if (houses[i].getId()==findId){
return houses[i]; //如果找到了 就返回当前数组元素里的全部信息,也就是房屋信息
}
}return null; //循环完了没找到 就返回空
}
3.增添房源功能
显示层:
//通过addHouse()接收输入,创建House对象,调用add方法
public void addHouse() {
System.out.println("------------添加房屋-----------");
System.out.println("姓名:");
String name = Utility.readString(8); //通过引用工具包静态方法实现录入输进去的字符串
System.out.println("电话:");
String phone = Utility.readString(11);
System.out.println("地址:");
String address = Utility.readString(12);
System.out.println("月租:");
int rent = Utility.readInt(5);
System.out.println("状态(已出租/未出租)");
String state = Utility.readString(3);
//创建一个新的House对象,id是系统分配的
House house = new House(0, name, phone, address, rent, state);
if (houseService.add(house)) { //这里我直接调用方法当条件 是因为我的判断逻辑写在方法里
System.out.println("添加房屋成功~~~~");
} else {
System.out.println("添加房屋失败~~~~");
}
}
业务层:
//增添房源,添加新对象,返回boolean
public boolean add(House newHouse) {
if (houseNum == houses.length) { //不能再添加了
System.out.println("数组已满,不能再添加了!!!");
return false;
}
//把newHouse对象新增到新加的房屋
houses[houseNum++] = newHouse;
//设计一个id自增机制
//调用set方法就是对返回的id进行控制 通过在方法里传入自增的idCounter来实现自增
idCounter++;
newHouse.setId(idCounter);
// newHouse.setId(++idCounter);
return true;
}
4.删除房源功能
显示层:
//编写delHouse()输入id,调用HouseService里的del()方法删除
public void delHouse() {
System.out.println("===========删除房屋信息===========");
System.out.println("请输入要删除的房屋编号(输入-1退出):");
int delId = Utility.readInt();
if (delId == -1) {
System.out.println("-----------退出删除操作~~-------------");
return;
}
//注意该方法本身就有循环判断的逻辑,必须输出Y/N
char choice = Utility.readConfirmSelection();
if (choice == 'Y') {
if (houseService.del(delId)) {
System.out.println("删除房屋信息成功!!!");
} else {
System.out.println("没有找到对应房屋信息,删除房屋信息失败~~~~");
}
} else {
System.out.println("=========放弃了删除房屋信息========");
}
}
业务层:
//del删除房屋信息方法
public boolean del(int delId){
//1.先找到要删除的房屋信息对应的下标!
int index=-1;
//!!!下标和房屋编号不是一回事 要区分清楚
for (int i = 0; i <houseNum; i++) {
if (delId == houses[i].getId()) { //保持类型一致
index = i; //使用index记录i
}
}
if (index==-1) { //说明输入的delId在getId里面找不到
return false;
}
//2.删除
for (int i=index;i<houseNum-1;i++){
//在找到要删除的对应房屋下标i之后 我就把他对应位置的后一个元素的地址给前一个,起到一个覆盖的作用间接实现删除
houses[i]=houses[i+1];
}
houses[houseNum]=null; //然后把i+1的元素地址滞空 两者相结合达到删除的效果
houseNum--;
return true;
}
5.修改房屋功能
无需分层,直接通过调用setName方法来修改
//修改房屋信息
public void update() {
System.out.println("==============修改房屋信息================");
System.out.println("请选择待修改房屋的编号~(-1退出)");
int updateId = Utility.readInt();
if (updateId == -1) {
System.out.println("============放弃修改房屋===========");
return;
}
//根据输入得到的updateId,查找对象
House house = houseService.findByid(updateId); //返回的是引用类型,就是数组里的元素
if (house == null) { //如果输入的编号不能找到的 就退出
System.out.println("您要修改的房屋不存在");
return;
}
System.out.print("姓名(" + house.getName() + "):");
String name = Utility.readString(4, "无"); //用户直接回车不修改,给一个默认值“无”
if (!"无".equals(name)) { //当我没有输入的要修改的name,直接回车,给的是默认值 就不满足修改的条件我就不会把值传给setName方法
house.setName(name); //修改操作 把新修改的值给setName方法达到修改的目的
}
System.out.print("电话(" + house.getPhone() + "):");
String phone = Utility.readString(11, "无");
if (!"无".equals(phone)) {
house.setPhone(phone); //修改操作
}
System.out.print("地址(" + house.getAddress() + "):");
String address = Utility.readString(10, "无");
if (!"无".equals(address)) {
house.setAddress(address); //修改操作
}
System.out.print("月租(" + house.getRent() + "):");
int rent = Utility.readInt(15);
if (!"无".equals(rent)) {
house.setRent(rent); //修改操作
}
System.out.print("状态(" + house.getState() + "):");
String state = Utility.readString(10, "无");
if (!"无".equals(state)) {
house.setState(state); //修改操作
}
System.out.println("修改成功~~~");
return ;
}
6.显示房源功能
显示层:
//调用list()方法,通过返回值显示出来
public void listHouse() {
System.out.println("=========房屋列表========");
System.out.println("编号\t房主\t\t电话\t\t\t地址\t\t\t月租\t\t状态(未出租/已出租)");
House[] houses = houseService.list(); //得到所有房屋信息了,遍历数组输出就可以显示
for (int i = 0; i < houses.length; i++) {
if (houses[i] == null) {
//这个逻辑的作用在于 当我循环遍历整个数组,房屋个数小于十个我就不会出现输出null的情况
break;
}
System.out.println(houses[i]);
}
System.out.println("-------------房屋列表显示完成-------------");
}
业务层:
//通过创建返回类型为House的方法返回已有的houses信息
public House[] list() { //注意这里是House[] 要注意类型一致
return houses;
}
7.退出校验功能
显示层:
//确认退回操作
public void backOf() { //此方法用于接收 然后在本类中调用
if (houseService.back()) { //用方法当判断条件,是因为逻辑在方法里已经体现了
System.out.println("您已经退出了系统~~~");
} else {
System.out.println("您刚刚竟然取消了操作!oh my god!");
}
}
业务层:
//确认退回操作
public boolean back(){
char choiceKey= Utility.readConfirmSelection(); // 确认Y/N工具
if (choiceKey=='Y'){ //读取的是Y就退出,反之
return true;
}
if (choiceKey=='N'){
}return false;
}
8.用户入口
public class HouseShow {
public static void main(String[] args) {
new HouseView().mainMenu(); //多学学这个调用类方法的写法 比以前实例化类用对象来调方法简洁,一句话搞定!
}
}
一个简单的功能可能需要复杂的逻辑去实现,更别说复杂的功能
路的尽头终究是路
写在最后:
==引用一个小伙伴儿的话:你间歇性的努力和蒙混过日子,都是对之前努力的清零。==