- 第9章 專案-房屋出租系統
- 房屋出租系統-需求
- 房屋出租系統-介面
- 專案介面- 主選單
- 專案介面- 新增房源
- 專案介面- 查詢房源
- 專案介面- 刪除房源
- 專案介面- 修改房源
- 專案介面- 房屋列表
- 專案介面- 退出系統
- 房屋出租系統-設計(!!)
- 房屋出租系統-實現
- 專案功能實現-完成House 類
- 專案功能實現-顯示主選單和完成退出軟體功能
- 專案功能實現-完成顯示房屋列表的功能
- 專案功能實現-新增房屋資訊的功能
- 專案功能實現-完成刪除房屋資訊的功能
- 專案功能實現-完善退出確認功能
- 專案功能實現-完成根據id查詢房屋資訊的功能
- 專案功能實現-完成修改房屋資訊的功能
第9章 專案-房屋出租系統
房屋出租系統-需求
實現基於文字介面的《房屋出租軟體》。
能夠實現對房屋資訊的新增、修改和刪除(用陣列實現),並能夠列印房屋明細表
房屋出租系統-介面
專案介面- 主選單
專案介面- 新增房源
專案介面- 查詢房源
專案介面- 刪除房源
專案介面- 修改房源
專案介面- 房屋列表
專案介面- 退出系統
房屋出租系統-設計(!!)
專案設計-程式框架圖(分層模式=>當軟體比較複雜,需要模式管理)
房屋出租系統-實現
準備工具類Utility,提高開發效率
在實際開發中,公司都會提供相應的工具類和開發庫,可以提高開發效率,程式設計師也需要能夠看懂別人寫的程式碼,並能夠正確的呼叫。
- 瞭解Utility 類的使用
- 測試Utility 類
專案功能實現-完成House 類
編號 房主 電話 地址 月租 狀態(未出租/已出租
package com.hspedu.houserent.domain;
/**
* House的物件表示一個房屋資訊
*/
public class House {
//編號 房主 電話 地址 月租 狀態(未出租/已出租)
private int id;
private String name;
private String phone;
private String address;
private int rent;
private String state;
//構造器和setter,getter
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;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getRent() {
return rent;
}
public void setRent(int rent) {
this.rent = rent;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
//為了方便的輸出物件資訊,我們實現toString
//編號 房主 電話 地址 月租 狀態(未出租/已出租)
@Override
public String toString() {
return id +
"\t\t" + name +
"\t" + phone +
"\t\t" + address +
"\t" + rent +
"\t" + state ;
}
}
專案功能實現-顯示主選單和完成退出軟體功能
實現功能的三部曲[明確完成功能->思路分析->程式碼實現]
功能說明: 使用者開啟軟體, 可以看到主選單,可以退出軟體.
思路分析: 在HouseView.java 中,編寫一個方法mainMenu,顯示選單.
package com.hspedu.houserent.view;
import com.hspedu.houserent.domain.House;
import com.hspedu.houserent.service.HouseService;
import com.hspedu.houserent.utils.Utility;
/**
* 1. 顯示介面
* 2. 接收使用者的輸入
* 3. 呼叫HouseService完成對房屋資訊的各種操作
*/
public class HouseView {
private boolean loop = true; //控制顯示選單
private char key = ' '; //接收使用者選擇
private HouseService houseService = new HouseService(2);//設定陣列的大小為2
//根據id修改房屋資訊
public void update() {
System.out.println("=============修改房屋資訊============");
System.out.println("請選擇待修改房屋編號(-1表示退出)");
int updateId = Utility.readInt();
if (updateId == -1) {
System.out.println("=============你放棄修改房屋資訊============");
return;
}
//根據輸入得到updateId,查詢物件
// 返回的是引用型別[即:就是陣列的元素]
// 因此老師在後面對house.setXxx() ,就會修改HouseService中houses陣列的元素!
House house = houseService.findById(updateId);
if (house == null) {
System.out.println("=============修改房屋資訊編號不存在..============");
return;
}
System.out.print("姓名(" + house.getName() + "): ");
String name = Utility.readString(8, "");//這裡如果使用者直接回車表示不修改該資訊,預設""
if (!"".equals(name)) {//修改
house.setName(name);
}
System.out.print("電話(" + house.getPhone() + "):");
String phone = Utility.readString(12, "");
if (!"".equals(phone)) {
house.setPhone(phone);
}
System.out.print("地址(" + house.getAddress() + "): ");
String address = Utility.readString(18, "");
if (!"".equals(address)) {
house.setAddress(address);
}
System.out.print("租金(" + house.getRent() + "):");
int rent = Utility.readInt(-1);
if (rent != -1) {
house.setRent(rent);
}
System.out.print("狀態(" + house.getState() + "):");
String state = Utility.readString(3, "");
if (!"".equals(state)) {
house.setState(state);
}
System.out.println("=============修改房屋資訊成功============");
}
//根據id查詢房屋資訊
public void findHouse() {
System.out.println("=============查詢房屋資訊============");
System.out.print("請輸入要查詢的id: ");
int findId = Utility.readInt();
//呼叫方法
House house = houseService.findById(findId);
if (house != null) {
System.out.println(house);
} else {
System.out.println("=============查詢房屋資訊id不存在============");
}
}
//完成退出確認
public void exit() {
//這裡我們使用Utility提供方法,完成確認
char c = Utility.readConfirmSelection();
if (c == 'Y') {
loop = false;
}
}
//編寫delHouse() 接收輸入的id,呼叫Service 的del方法
public void delHouse() {
System.out.println("=============刪除房屋資訊============");
System.out.print("請輸入待刪除房屋的編號(-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("=============放棄刪除房屋資訊============");
}
}
//編寫addHouse() 接收輸入,建立House物件,呼叫add方法
public void addHouse() {
System.out.println("=============新增房屋============");
System.out.print("姓名: ");
String name = Utility.readString(8);
System.out.print("電話: ");
String phone = Utility.readString(12);
System.out.print("地址: ");
String address = Utility.readString(16);
System.out.print("月租: ");
int rent = Utility.readInt();
System.out.print("狀態: ");
String state = Utility.readString(3);
//建立一個新的House物件, 注意id 是系統分配的,
House newHouse = new House(0, name, phone, address, rent, state);
if (houseService.add(newHouse)) {
System.out.println("=============新增房屋成功============");
} else {
System.out.println("=============新增房屋失敗============");
}
}
//編寫listHouses()顯示房屋列表
public void listHouses() {
System.out.println("=============房屋列表============");
System.out.println("編號\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("=============房屋列表顯示完畢============");
}
//顯示主選單
public void mainMenu() {
do {
System.out.println("\n=============房屋出租系統選單============");
System.out.println("\t\t\t1 新 增 房 源");
System.out.println("\t\t\t2 查 找 房 屋");
System.out.println("\t\t\t3 刪 除 房 屋 信 息");
System.out.println("\t\t\t4 修 改 房 屋 信 息");
System.out.println("\t\t\t5 房 屋 列 表");
System.out.println("\t\t\t6 退 出");
System.out.print("請輸入你的選擇(1-6): ");
key = Utility.readChar();
switch (key) {
case '1':
addHouse();
break;
case '2':
findHouse();
break;
case '3':
delHouse();
break;
case '4':
update();
break;
case '5':
listHouses();
break;
case '6':
exit();
break;
}
} while (loop);
}
}
專案功能實現-完成顯示房屋列表的功能
專案功能實現-新增房屋資訊的功能
專案功能實現-完成刪除房屋資訊的功能
專案功能實現-完善退出確認功能
專案功能實現-完成根據id查詢房屋資訊的功能
專案功能實現-完成修改房屋資訊的功能
package com.hspedu.houserent.service;
import com.hspedu.houserent.domain.House;
/**
* HouseService.java<=>類 [業務層]
* //定義House[] ,儲存House物件
* 1. 響應HouseView的呼叫
* 2. 完成對房屋資訊的各種操作(增刪改查c[create]r[read]u[update]d[delete])
*/
public class HouseService {
private House[] houses; // House 陣列 儲存House物件
private int houseNums = 1; //記錄當前有多少個房屋資訊
private int idCounter = 1; //記錄當前的id增長到哪個值
//構造器
public HouseService(int size) {
//new houses
houses = new House[size];//當建立HouseService物件,指定陣列大小
//為了配合測試列表資訊,這裡初始化一個House物件
houses[0] = new House(1,"jack","112", "海淀區", 2000, "未出租");
}
// findById方法,返回House物件或者null
public House findById(int findId) {
//遍歷陣列
for(int i = 0; i < houseNums; i++) {
if(findId == houses[i].getId()) {
return houses[i];
}
}
return null;
}
//del方法,刪除一個房屋資訊
public boolean del(int delId) {
// 應當先找到要刪除的房屋資訊對應的下標
// 一定要搞清楚 下標和房屋的編號不是一回事
int index = -1;
for(int i = 0; i < houseNums; i++) {
if(delId == houses[i].getId()) {// 要刪除的房屋(id),是陣列下標為i的元素
index = i;// 就使用index記錄i
}
}
if(index == -1) {//說明delId在陣列中不存在(有點繞..)
return false;
}
// 如果找到
for(int i = index; i < houseNums - 1; i++) {
houses[i] = houses[i+1];
}
// 把當有存在的房屋資訊的最後一個 設定null
houses[--houseNums] = null;
return true;
}
// add方法,新增新物件,返回boolean
public boolean add(House newHouse) {
// 判斷是否還可以繼續新增(我們暫時不考慮陣列擴容的問題) => 能否自己加入陣列擴容機制(~~)
if(houseNums == houses.length) {//不能再新增
System.out.println("陣列已滿,不能再新增了...");
return false;
}
// 把newHouse物件加入到,新增加了一個房屋
houses[houseNums++] = newHouse;
// 我們程式設計師需要設計一個id自增長的機制, 然後更新 newHouse 的id!
newHouse.setId(++idCounter);
return true;
}
//list方法,返回houses
public House[] list() {
return houses;
}
}
類.方法() => 因為當一個方法是static時,就是一個靜態方法
最後 HouseRentApp.java
package com.hspedu.houserent;
import com.hspedu.houserent.view.HouseView;
public class HouseRentApp {
public static void main(String[] args) {
byte b1 = 123;
b1 += 100000; //如果 b1 = b1 + 100000;//編譯都不能過
System.out.println(b1);
byte b2 = 123;
b2 = (byte)(b2 + 100000);
System.out.println(b2);
// 建立HouseView匿名物件,並且顯示主選單,是整個程式的入口
// 這裡實際上不用接收了,因為接收後用處也不大:
// new hv = new HouseView();
// hv.mainMenu();
new HouseView().mainMenu();
System.out.println("===你退出房屋出租系統==");
}
}
附:公用工具庫 Utility.java
package com.hspedu.houserent.utils;
/**
工具類的作用:
處理各種情況的使用者輸入,並且能夠按照程式設計師的需求,得到使用者的控制檯輸入。
*/
import java.util.*;
/**
*/
public class Utility {
//靜態屬性。。。
private static Scanner scanner = new Scanner(System.in);
/**
* 功能:讀取鍵盤輸入的一個選單選項,值:1——5的範圍
* @return 1——5
*/
public static char readMenuSelection() {
char c;
for (; ; ) {
String str = readKeyBoard(1, false);//包含一個字元的字串
c = str.charAt(0);//將字串轉換成字元char型別
if (c != '1' && c != '2' &&
c != '3' && c != '4' && c != '5') {
System.out.print("選擇錯誤,請重新輸入:");
} else break;
}
return c;
}
/**
* 功能:讀取鍵盤輸入的一個字元
* @return 一個字元
*/
public static char readChar() {
String str = readKeyBoard(1, false);//就是一個字元
return str.charAt(0);
}
/**
* 功能:讀取鍵盤輸入的一個字元,如果直接按回車,則返回指定的預設值;否則返回輸入的那個字元
* @param defaultValue 指定的預設值
* @return 預設值或輸入的字元
*/
public static char readChar(char defaultValue) {
String str = readKeyBoard(1, true);//要麼是空字串,要麼是一個字元
return (str.length() == 0) ? defaultValue : str.charAt(0);
}
/**
* 功能:讀取鍵盤輸入的整型,長度小於2位
* @return 整數
*/
public static int readInt() {
int n;
for (; ; ) {
String str = readKeyBoard(10, false);//一個整數,長度<=10位
try {
n = Integer.parseInt(str);//將字串轉換成整數
break;
} catch (NumberFormatException e) {
System.out.print("數字輸入錯誤,請重新輸入:");
}
}
return n;
}
/**
* 功能:讀取鍵盤輸入的 整數或預設值,如果直接回車,則返回預設值,否則返回輸入的整數
* @param defaultValue 指定的預設值
* @return 整數或預設值
*/
public static int readInt(int defaultValue) {
int n;
for (; ; ) {
String str = readKeyBoard(10, true);
if (str.equals("")) {
return defaultValue;
}
//異常處理...
try {
n = Integer.parseInt(str);
break;
} catch (NumberFormatException e) {
System.out.print("數字輸入錯誤,請重新輸入:");
}
}
return n;
}
/**
* 功能:讀取鍵盤輸入的指定長度的字串
* @param limit 限制的長度
* @return 指定長度的字串
*/
public static String readString(int limit) {
return readKeyBoard(limit, false);
}
/**
* 功能:讀取鍵盤輸入的指定長度的字串或預設值,如果直接回車,返回預設值,否則返回字串
* @param limit 限制的長度
* @param defaultValue 指定的預設值
* @return 指定長度的字串
*/
public static String readString(int limit, String defaultValue) {
String str = readKeyBoard(limit, true);
return str.equals("")? defaultValue : str;
}
/**
* 功能:讀取鍵盤輸入的確認選項,Y或N
* 將小的功能,封裝到一個方法中.
* @return Y或N
*/
public static char readConfirmSelection() {
System.out.println("請輸入你的選擇(Y/N): 請小心選擇");
char c;
for (; ; ) {//無限迴圈
//在這裡,將接受到字元,轉成了大寫字母
//y => Y n=>N
String str = readKeyBoard(1, false).toUpperCase();
c = str.charAt(0);
if (c == 'Y' || c == 'N') {
break;
} else {
System.out.print("選擇錯誤,請重新輸入:");
}
}
return c;
}
/**
* 功能: 讀取一個字串
* @param limit 讀取的長度
* @param blankReturn 如果為true ,表示 可以讀空字串。
* 如果為false表示 不能讀空字串。
*
* 如果輸入為空,或者輸入大於limit的長度,就會提示重新輸入。
* @return
*/
private static String readKeyBoard(int limit, boolean blankReturn) {
//定義了字串
String line = "";
//scanner.hasNextLine() 判斷有沒有下一行
while (scanner.hasNextLine()) {
line = scanner.nextLine();//讀取這一行
//如果line.length=0, 即使用者沒有輸入任何內容,直接回車
if (line.length() == 0) {
if (blankReturn) return line;//如果blankReturn=true,可以返回空串
else continue; //如果blankReturn=false,不接受空串,必須輸入內容
}
//如果使用者輸入的內容大於了 limit,就提示重寫輸入
//如果使用者如的內容 >0 <= limit ,我就接受
if (line.length() < 1 || line.length() > limit) {
System.out.print("輸入長度(不能大於" + limit + ")錯誤,請重新輸入:");
continue;
}
break;
}
return line;
}
}