ThoughtWorks 2018校园招聘作业题目——出租车
本文描述家庭作业中部分模块的功能,以及项目正确性判断
家庭作业部分
模块划分
- Main主函数,负责输入输出,以及程序顺序调节
- vo包,提供Car对象的封装,Car对象封装了汽车相关信息,以及提供相关属性的构造器
- Check包,提供Car的检查,并且生成报表
- Processor包,提供汽车处理函数,能够采用链式表达式方式进行处理
- Result包,提供结果输出功能
- Utils包,工具类,主要是时间的处理方法
详细功能
主函数采取用户输入方式获得汽车信息,并将汽车信息封装为Car对象后交由Processor对象处理,下面是处理函数
while(true) {
try {
Car.setSubmitDate(df.parse(submit));
break;
} catch (ParseException e) {
System.out.println("input error,the submit date has wrong format.");
submit = sc.nextLine().substring(submitPrefix.length());
}
}
CarProcessor carProcessor = new CarProcessor();
while(sc.hasNextLine()){
Car car = new Car();
String line = sc.nextLine();
if(line.equals("EOF"))
break;
String[] carInfo = line.split("\\|");
car.setBrand(carInfo[2]);
car.setPlateNumber(carInfo[0]);
car.setOverhauled(carInfo[4].trim().equals("T"));
try {
car.setMiles(Integer.parseInt(carInfo[3]));
car.setPurchaseDate(df.parse(carInfo[1]));
}catch (NumberFormatException e){
System.out.println("input car miles format wrong");
}catch (ParseException e){
System.out.println("input car purchase date wrong");
}
carProcessor.setCar(car);
}
Checker包主要提供三个方法
第一个方法:
List<Car> getRemainCars();
此方法能够获得经过该checker处理后的car列表,如果没有设置checker的属性remove为NOT_REMOVE,那么该方法将会返回当初set的值,如果设置remove为REMOVE,那么将会返回处理结束的剩余Car列表
第二个方法
IResultHandler getResult();
此方法能够获得经过该Checker处理后,得到的Result
第三个方法:
void setCars(List cars);
设置汽车list,方便处理
processor包提供流程处理
private List<Car> cars;
private IChecker checker;
private List<IResultHandler> resultHandler = new ArrayList<>();
其中保存了流程中的checker以及car的列表
在主函数中通过如下形式进行顺序处理,此种方式方便进行顺序的修改,通过不同的顺序来达到不同的生成结果
/** * 进行处理 */
carProcessor
.writeOffCheck()
.distanceMaintenCheck()
.timeMaintenCheck()
.generateReport();
Result包中主要提供生成报告的方法
/** * this function will generate a result report according to the car list set in */
void generateResult();
/** * car need to generate report * @param cars */
void setCars(List<Car> cars);
/** * 获取排序优先级 * @return */
int getSort();
DateUtils提供对于日期的处理
public class DateUtils {
public static int getYears(Car car){
Calendar purchase = getPurchaseCalendar(car);
Calendar submit = getSubmitCalendar();
return submit.get(Calendar.YEAR) - purchase.get(Calendar.YEAR);
}
public static int getMonth(Car car){
int years = getYears(car);
Calendar purchase = getPurchaseCalendar(car);
Calendar submit = getSubmitCalendar();
return years * 12 + submit.get(Calendar.MONTH) - purchase.get(Calendar.MONTH);
}
public static Calendar getPurchaseCalendar(Car car){
Calendar.Builder cb = new Calendar.Builder();
cb.setInstant(car.getPurchaseDate());
return cb.build();
}
public static Calendar getSubmitCalendar(){
Calendar.Builder cb = new Calendar.Builder();
cb.setInstant(Car.getSubmitDate());
return cb.build();
}
}
程序测试
处理程序输入,测试用例以EOF作为最后的输入结束标志:
测试用例1:
输入:
SubmitDate: 2050/05/01
CAR0001|2044/05/01|Volkswagen|65535|F
CAR0002|2044/05/03|BMW|100001|F
CAR0003|2047/05/02|Mercedes-Benz|37789|T
CAR0004|2047/05/03|Honda|59908|T
CAR0005|2049/12/10|Peugeot|49999|F
CAR0006|2046/11/15|Jeep|2000|F
CAR0007|2046/11/16|Jeep|5000|F
EOF
输出结果:
Reminder
==================
* Time-related maintenance coming soon...
Audi: 1 (CAR0006)
Porsche: 1 (CAR0002)
* Distance-related maintenance coming soon...
BYD: 1 (CAR0005)
Ford: 1 (CAR0007)
Porsche: 1 (CAR0001)
* Write-off coming soon...
BYD: 1 (CAR0004)
Ford: 1 (CAR0009)
测试与预期完全一致
本次测试覆盖率:
Checker:
Result:
结论:
- Checker中覆盖率,checker工厂方法完全覆盖,除了部分getter与setter以及默认构造器,因此认为工厂方法测试通过。
Checker中报废checker完全通过,距离checker完全覆盖,时间保养checker覆盖率较低,未覆盖代码:
也就是车辆保养日期恰好位于保修日期相同月份尚未测试Result覆盖率100%通过,因此测试通过
测试用例2:
输入:
SubmitDate: 2050/05/01
CAR0001|2044/05/01|Volkswagen|65535|F
CAR0002|2044/05/03|BMW|100001|F
CAR0003|2047/05/02|Mercedes-Benz|37789|T
CAR0004|2047/05/03|Honda|59908|T
CAR0005|2049/12/10|Peugeot|49999|F
CAR0006|2046/11/15|Jeep|2000|F
CAR0007|2046/11/16|Jeep|5000|F
EOF
输出:
Reminder
==================
* Time-related maintenance coming soon...
Jeep: 2 (CAR0007,CAR0006)
* Distance-related maintenance coming soon...
Peugeot: 1 (CAR0005)
* Write-off coming soon...
BMW: 1 (CAR0002)
Honda: 1 (CAR0004)
与预期结果完全一致
本次测试覆盖率:
Checker
Result
结论:
- 本次测试,覆盖了测试用例1中未经过测试的代码,所有代码覆盖率达到100%,同时输出结果与预期完全一致,判断作业正确