一直觉得要面向对象,那就必须分析对象的特点,进行完全面向对象。
比如在快递柜管理系统,显而易见肯定有快递对象Express、柜子对象ExpressDao,但是快递实际放在具体的格子里,所以还需要有格子对象Cabinet。
- 接下来分析对象的属性。
-
快递对象Express:快递单号,快递公司
为什么没有取件码?
我想的是,一个快递如果不放到快递柜、而是直接给收件人,那怎么会有取件码呢?所以取件码肯定是跟着快递柜的,有快递柜,才有取件码。 -
柜子对象ExpressDao:一个个格子,格子总数
一个个格子是一堆对象了,需要考虑用适合的数据结构存储这一堆对象。
为什么是格子总数,而不是行总数、列总数?
因为快递柜格子有大小之分,实际去观察快递柜,没法数出确定的行总数、列总数,因此用格子总数代替。
如果再细分,应该定义格子接口/父类,用大中小格子去实现/继承格子接口/父类。 -
格子对象Cabinet:坐标x、y,取件码,存放空间
后期在思考怎么把快递跟格子联系起来时,想不到别的办法,就又加了个快递对象属性。
希望能知道更准确、不冗余的做法。
- 最后分析对象方法
- 快递对象Express:实例化constructor,设置各个属性setter,获取各个属性getter
- 柜子对象ExpressDao:存入快递,根据取件码取出快递
- 格子对象Cabinet:找到一个空柜子放入快递,根据取件码找到对应柜子里的东西
理想很丰满,现实很骨感,目前暂时实现了一部分。
Express.java
package bean;
/**
* only Express
*/
public class Express {
// attributes
private String number;// 快递单号
private String company;// 快递公司
// constructor
public Express(String number, String company) {
if ("".equals(number) || "".equals(company)){
throw new RuntimeException("快递单号或快递公司没填。");
}
else {
this.number = number;
this.company = company;
}
}
@Override
public String toString() {
return "Express{" +
"number='" + number + '\'' +
", company='" + company + '\'' +
'}';
}
}
Cabinet.java
package bean;
/**
* 快递格子
*/
public class Cabinet {
// attr
private Integer x;
private Integer y;
private Integer code;
private Express express;
//constructor
public Cabinet(Integer x, Integer y, Integer code, Express express) {
this.x = x;
this.y = y;
this.code = code;
this.express = express;
}
public Integer getX() {
return x;
}
public Integer getY() {
return y;
}
public Integer getCode() {
return code;
}
public void setX(Integer x) {
this.x = x;
}
public void setY(Integer y) {
this.y = y;
}
public void setCode(Integer code) {
this.code = code;
}
public void setExpress(Express express) {
this.express = express;
}
@Override
public String toString() {
return "Cabinet{" +
"x=" + x +
", y=" + y +
", code=" + code +
", express=" + express.toString() +
'}';
}
}
CabinetDao.java
package dao;
import bean.Cabinet;
import bean.Express;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* 快递柜类
*/
public class CabinetDao {
// attr
private List<Cabinet> cabinetList = new ArrayList<>(100);
// constructor
public CabinetDao() { }
public CabinetDao(List<Cabinet> cabinetList) {
this.cabinetList = cabinetList;
}
public void toStringCustom() {
for (Cabinet cabinet: cabinetList){
System.out.println(cabinet.toString());
}
}
public boolean addExpress(Express express){
// 判断柜子是否已满
if (cabinetList.size()==100) {
throw new ArrayIndexOutOfBoundsException("快递柜已满。");
}
// 判断快递信息是否合法,构造Express时应该检查
// 生成快递柜坐标
Random random = new Random();
int x, y;
do {
x = random.nextInt(100);
y = random.nextInt(100);
}while (!isEmpty(x, y));
// 还要生成取件码
int code;
do {
code = random.nextInt(899999)+10000;
}while (findByCode(code)!=null);
// 指定格子里面放入快递,List的add返回boolean
cabinetList.add(new Cabinet(x, y, code, express));
return true;
}
// 判断指定快递柜是否为空
private boolean isEmpty(int x, int y){
for (Cabinet cabinet: this.cabinetList) {
if (cabinet.getX()==x && cabinet.getY()==y) return false;
}
return true;
}
// 判断取件码是否重复
private Cabinet findByCode (int code){
for (Cabinet cabinet: this.cabinetList) {
if (cabinet.getCode()==code) return cabinet;
}
return null;
}
}
View.java
package view;
import bean.Express;
import dao.CabinetDao;
import java.util.Scanner;
public class View {
Scanner input = new Scanner(System.in);
CabinetDao cabinetDao = new CabinetDao();
// 快递员添加快递
public void addExpress(){
System.out.println("输入快递单号:");
String number = input.nextLine();
System.out.println("请输入快递公司:");
String company = input.nextLine();
// 存入快递,留给业务去校验合法性
Express express = new Express(number, company);
try {
cabinetDao.addExpress(express);
}catch (ArrayIndexOutOfBoundsException e){
System.out.println(e.getMessage());
}
}
// 展示快递
public void display(){
cabinetDao.toStringCustom();
}
}
Main.java
package main;
import view.View;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
View view = new View();
view.addExpress();
view.display();
}
}
运行效果