lab4

    1. Error and Exception Handling
      1. 处理输入文本中的三类错误

DataPatternException

在正则表达式匹配时,若没有匹配到则抛出该错误

if (!matcher.find()) {

      try {throw new DataPatternException("mismatch");}

      catch(DataPatternException e){

      logger.log(Level.SEVERE, e.getMessage(), e); //日志

      System.out.println("mismatch");///1///

      }

 

EntryNumberFormatException

检查是否符合“前两个字符为大写字母,后2-4个字符为数字

int flag2=0;

    if (Character.isUpperCase(planningEntryNumber.charAt(0))

            && Character.isUpperCase(planningEntryNumber.charAt(1))) {

        for (int i = 2; i < planningEntryNumber.length(); i++) {

            if (!Character.isDigit(planningEntryNumber.charAt(i))) {

             try {throw new EntryNumberFormatException(planningEntryNumber + " has incorrect EntryNumberformat.");}

               catch(EntryNumberFormatException e){

                logger.log(Level.SEVERE, e.getMessage(), e); //日志

                System.out.println(planningEntryNumber + " has incorrect EntryNumberformat.");}

             flag2=1;

            }

               

        }

    } else   {

     try {throw new EntryNumberFormatException(planningEntryNumber + " has incorrect EntryNumberformat.");}

             catch(EntryNumberFormatException e){

              logger.log(Level.SEVERE, e.getMessage(), e); //日志

              System.out.println(planningEntryNumber + " has incorrect EntryNumberformat.");}

     flag2=1;

    }

    return flag2;

 

SameAirportException

两个机场字符串是否相等。

TimeOrderException

起飞时间应该在到达时间之前

if(time.getbegin().getMillis()>time.getend().getMillis()) {

try {throw new TimeOrderException(" TimeOrder.");}

            catch(TimeOrderException e){

              logger.log(Level.SEVERE, e.getMessage(), e); //日志

             System.out.println( " TimeOrder.");}///4///

 

PlaneNumberFormatException

飞机编号不符合格式,检查字符串长度以及首字母、后4位数字

int flag5=0;

if(planNumber.length()!=5) {

try {throw new PlaneNumberFormatException(planNumber + "  incorrect PlanNumberlenth.");}

            catch(PlaneNumberFormatException e){

              logger.log(Level.SEVERE, e.getMessage(), e); //日志

             System.out.println(planNumber + "  incorrect PlanNumberlenth.");}

 flag5=1;

}

 

 

    if (planNumber.charAt(0)=='N'||planNumber.charAt(0)=='B') {

        for (int i = 1; i < planNumber.length(); i++) {

            if (!Character.isDigit(planNumber.charAt(i))) {

             try {throw new PlaneNumberFormatException(planNumber + " has incorrect PlanNumberformat.");}

               catch(PlaneNumberFormatException e){

                logger.log(Level.SEVERE, e.getMessage(), e); //日志

                System.out.println(planNumber + " has incorrect PlanNumberformat.");}

             flag5=1;

            }

               

        }

    } else   {

     try {throw new PlaneNumberFormatException(planNumber + " has incorrect PlanNumberformat.");}

             catch(PlaneNumberFormatException e){

              logger.log(Level.SEVERE, e.getMessage(), e); //日志

              System.out.println(planNumber + " has incorrect PlanNumberformat.");}

     flag5=1;

    }

  return flag5;  

PlaneTypeException

飞机类型不符合格式检查是否由字母和数字构成。

 

PlaneSeatRangeException

飞机座位数范围错误转换为整数比较范围。

 

PlaneAgeFormatException

飞机年龄非一位小数或整数,查找小数点的位置,字符串比较,

 

SameEntryException

存在两个航班,飞机和航班号都相等。

 

HugeTimeGapException

起飞时间和到达时间超过一天。

 

EntryInconsistentInfoException

相同航班号的航班信息起降时间不一致。

 

InconsistentdatesException

航班计划项日期不一致

 

EntryLocationInfoException

相同航班号的航班信息起降地点不一致。

 

 

 

 

      1. 处理客户端操作时产生的异常

DeleteAllocatedResourceException在删除某资源的时候,如果有尚未结束的计划项正在占用该资源

for(ActivityEntry<activityresource> p:actlist) {

if(p.getres().getname().equals(Name)) {

if(!(p.getstate().equals("ENDED"))) {

///System.out.println( "222");

try {throw new DeleteAllocatedResourceException( "  DeleteAllocatedResource.");} ///2.1///

            catch(DeleteAllocatedResourceException e){System.out.println( "  DeleteAllocatedResource.");}

return false;

}

}

 

}

 

DeleteOccupiedLocationException

原因:在删除某位置的时候,如果有尚未结束的计划项正在该位置执行

 

for(ActivityEntry<activityresource> p:actlist) {

if(p.getlocation().getname().equals(loc)) {

if(!(p.getstate().equals("ENDED"))) {

try {throw new DeleteOccupiedLocationException( "  DeleteOccupiedLocation.");} ///2.2///

            catch(DeleteOccupiedLocationException e){System.out.println( "  DeleteOccupiedLocation.");}

return false;

}

}

 

}

 

 

UnableCancelException

在取消某计划项的时候,如果该计划项的当前状态不允许取消

 

switch (c) {

//返回新状态白

case "cancel":try {throw new UnableCancelException(" UnableCancel.");}

        catch(UnableCancelException e){

         logger.log(Level.SEVERE, e.getMessage(), e); //日志

         System.out.println( " UnableCancel.");}///2.3///

 

 

 

ResourceSharedException

在为某计划项分配某资源的时候,如果分配后会导致与已有的其他计划项产生“资源独占冲突”

 

for(PlaneEntry<planeresource> a:plalist)

{

if((!(a.getstate().equals("WAITING")))&&a.getres().getnumber().equals(resname)) {

if(!(a.getstate().equals("ENDED"))) {

try {throw new ResourceSharedException( "  ResourceSharedException.");} ///2.4///

            catch(ResourceSharedException e){

              logger.log(Level.SEVERE, e.getMessage(), e); //日志

             System.out.println( "  ResourceSharedException.");}

 

return;

}

 

}

}

 

 

 

LocationSharedException

在为某计划项变更位置的时候,如果变更后会导致与已有的其他计划项产生“位置独占冲突”

 

for(ActivityEntry<activityresource> p:actlist) {

if(p.getlocation().getname().equals(newloc)) {

if(!(p.getstate().equals("ENDED"))) {

try {throw new DeleteOccupiedLocationException( "  DeleteOccupiedLocation.");} ///2.5///

            catch(DeleteOccupiedLocationException e){System.out.println( "  DeleteOccupiedLocation.");}

return ;

}

}

 

}

    1. Assertion and Defensive Programming
      1. checkRep()检查rep invariants

TimeSlot

/*

 * AF:

 * begin出发时间,end到达时间

 *

 *

 * RI:

 * 不为空 到达晚于出发

 *

 * Safety:

 * private

 */

 

Location

private void checkRep() {

    assert (begin.getMillis()<  end.getMillis());

    

}

 

// Abstraction function:

    //   用经纬度longitude latitude;名称name 共享shareable属性表示地点

    // Representation invariant:

    //   不为空

    // Safety from rep exposure:

    //   使用private 防御编程

 

private void checkRep() {

 assert(name!=null);

}

EntryState

/*

 * AF:

 * the state name represents the state

 * RI:

 * state must change as required

 * Safety:

 * it's a mutable object

 */

 

planeresource

// Abstraction function:

    //   编号number型号type人数people年龄age

    // Representation invariant:

    //   不为空

    // Safety from rep exposure:

    //   使用private 防御编程

 

private void checkRep() {

assert (number!=null);

 assert (type!=null);

 assert (people!=null);

 assert (age!=null);

}

 

Trainresource

// Abstraction function:

    //   编号number型号type人数people年龄age

    // Representation invariant:

    //   不为空

    // Safety from rep exposure:

    //   使用private 防御编程

 

private void checkRep() {

assert (number!=null);

 assert (type!=null);

 assert (people!=null);

 assert (age!=null);

}

 

 

activityresource

// Abstraction function:

    //   名称name部门department日期date数量number

    // Representation invariant:

    //   不为空,number>0

    // Safety from rep exposure:

//   使用private 防御编程

private void checkRep() {

assert (name!=null);

 assert (department!=null);

 assert (date!=null);

 assert (number>0);

}

 

 

 

 

PlanningEntry

/**

 * a factory method for generating an instance of PlaneEntry

 * @param <R>

 * @return an empty instance of planning entry of PlaneEntry

 */

public static <R> PlaneEntry<R> newPlanningEntryOfPlane() {

    return new PlaneEntry<R>();

}

 

 

 

/**

 * a factory method for generating an instance of TrainEntry

 * @param <R>

 

 * @return an empty instance of planning entry of TrainEntry

 */

public static <R> TrainEntry<R> newPlanningEntryOfTrain() {

return new TrainEntry<R>();

}

 

 

 

/**

 * a factory method for generating an instance of ActivityEntry

 * @param <R>

 

 * @return an empty instance of planning entry of ActivityEntry

 */

public static <R> ActivityEntry<R> newPlanningEntryOfActivity() {

    return new ActivityEntry<R>();

}

 

/**

 * start the planning entry

 

 */

public void start();

 

/**

 * cancel the planning entry

 

 */

public void cancel();

 

/**

 * complete the planning entry

 

 */

public void complete();

 

/**

 * allocate the planning entry state

 

 */

public void allocate();

 

      1. Assertion/异常机制来保障pre-/post-condition

EntryState通过switch限制状态只能合法变换,只有高铁有block的方法

在分配资源时先查询是否存在资源

 

      1. 你的代码的防御式策略概述

在客户端输入的时候对其数据进行检查,在adt中再次检查

    1. Logging
      1. 异常处理的日志功能

private final static Logger logger = Logger.getLogger("Flight Schedule Log");{

Locale.setDefault(new Locale("en", "EN"));

logger.setLevel(Level.INFO);

FileHandler fileHandler;

try {

fileHandler = new FileHandler("src/txt/FlightScheduleLog.txt", true);

fileHandler.setFormatter(new SimpleFormatter());

logger.addHandler(fileHandler);

} catch (SecurityException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

 

}//日志

本实验中,日志功能的实现调用了 Java 的库 java.util.logging。

private final static Logger logger = Logger.getLogger("Flight Schedule Log");

 

日志配置。

首先配置日志的输出语言为英文。

 

Locale.setDefault(new Locale("en", "EN"));

 

然后设置日志显示信息的最低级别(

 

logger.setLevel(Level.INFO);

 

加入相应的文件管理,使得日志可以写入到文件中。

 

FileHandler fileHandler = new FileHandler("log/FlightScheduleLog.txt", true);

 

fileHandler.setFormatter(new SimpleFormatter());

logger.addHandler(fileHandler);

      1. 应用层操作的日志功能
      2. 日志查询功能
    1. Testing for Robustness and Correctness
      1. Testing strategy

测试各类异常是否正确触发

      1. 测试用例设计

文件测试用例在test/txt/

 

 

客户端异常测试节选

@Test 

public void ResourceSharedExceptiontest2() throws  DeleteOccupiedLocationException,Exception {

    //exception.expect(DeleteAllocatedResourceException.class);

   // exception.expectMessage("xinhua 正在被占用");

FlightScheduleApp app = new FlightScheduleApp();

app.AddLocation("a1");

app.AddLocation("a2");

app.CreatPla("CZ001", "a1", "a2", "2020-01-08 20:48", "2020-01-08 21:48");

app.CreatPla("CZ002", "a1", "a2", "2020-02-08 20:48", "2020-02-08 21:48");

app.CreatRes("2", "A001", "N001", "100");

app.allocateres("CZ001", "N001");

app.allocateres("CZ002", "N001");

//app.StartPlanningEntry("2020-01-08,502");

 

 

}

 

@Test 

public void ResourceSharedExceptiontest1() throws  DeleteAllocatedResourceException,Exception {

List<trainresource> rs= new ArrayList<trainresource>();

List<Location> ls= new ArrayList<Location>();

List<Timeslot> ts=new ArrayList<Timeslot>();

TrainScheduleApp app = new TrainScheduleApp();

app.AddLocation("a1");

app.AddLocation("a2");

for(Location l:app.loclist)

{

if(l.getname().equals("a1")||l.getname().equals("a2")) {

ls.add(l);

 

}

}

app.CreatRes("2", "A001", "N001", "100");

app.CreatRes("2", "A001", "N002", "100");

for(trainresource l:app.reslist)

{

if(l.getnumber().equals("N001")||l.getnumber().equals("N002")) {

rs.add(l);

 

}

}

Timeslot t=new Timeslot("2020-01-08 20:48", "2020-01-08 21:48");

ts.add(t);

app.CreatTra("Z001", ls, ts);

app.CreatTra("Z002", ls, ts);

app.allocateres("Z001", rs);

app.allocateres("Z002", rs);

 

 

}

 

      1. 测试运行结果与EclEmma覆盖度报告

测试结果在src/txtd的日志中

 

    1. SpotBugs tool

没有发现错误,在修改的过程中出现过越界问题。

    1. Debugging
      1. EventManager程序

将区间的每一个整数点进行标记(用Map),查找Map.values()最大值。

通过测试发现空指针异常,没有对对应key值进行判断。判断后进行初始化,每次遇到start对对应value值加1,遇到end对对应value值-1,然后通过有序的遍历,进行最大值的筛选,可以得到一年中的最大k值。最后将日期换算成小时,并进行异常判断。

 

      1. LowestPrice程序

在有special offer的情况下最优价格。使用贪心算法。假设最低代价为全用零售,然后每次将一个special offer加入“购物车”,更新,再迭代求解,测试可知如果差值为负数应该直接break并且等于0时可以继续进行,由于特殊价格链表本身就比商品长度多出价格,所以迭代是不用-1最后加入异常判断。

 

      1. FlightClient/Flight/Plane程序

通过枚举每个航班,尝试安排飞机,确保没有与其他已经分配的航班冲突,最后确认是否能所有同时分配成功。

字符串的==判断应替换为.equals

根据编译器的静态检查sort并不能直接对List<Flight>使用,改成before()以及after()

经过调试可以发现即使遍历完所有飞机,但无法跳出while循环,所以对随机选择飞机进行修改,调用过的飞机将他排除在下一次随机选择范围外,并计数,达到飞机个数时跳出循环。将bAllocated当做标志变量,在分配完后不使用break跳出循环,而选择更改bAllocated的值为true,若发现bAllocated为false,将bFeasible改为false并返回。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值