第三单元总结作业

本单元直接给出基于JML的规格说明,因此在编写程序的时候,只需要认真阅读前置条件以及后置条件,抛出的异常等内容就可以实现代码。规格为数据规格和方法规格两种,而方法的实现需要基于数据的组织形式。

在规格实现中,基于数据类型直接按照规格来写也可以,数组可以使用Java提供的容器类比如Linkedlist或者ArrayList。如果需要在两个数组中找到对应值就可以使用Map来实现映射以提高查找效率。在第三次作业的Network很容易超过500行,因此需要对一些冗余代码删掉,检查哪一些部分是重合,可以把一些重合的部分抽出来,新建一个方法来进行调用。

第一次作业acquaintance把Person的id和value使用Map来对应存储为了后面方便访问。在第一作业被hack的bug是自己忽略到输出异常的id错误。修复bug之后没注意截止时间忘了提交觉得很可惜。这一次作业很容发现到别人的bug,也是本人第一次进到互测。

第二次作业最难部分是实现queryLeastConnection,是一个最小生成树。一开始对JML解析时有点困难,最后理解了但是实现时有一些错误。

第三次作业最难部分是实现一个简接发消息,需要找一个最短路径,使用Djikstra方法就可以实现,在本作业我创建新类叫MyPath存储所有点的边和权重,然后使用shortestPath方法来找两个节点之间的最短路径,使用优先队列容器Priority Queue来实现。中测时发现deletecoldemoji的实现方法无法在for循环直接remove,因此自己找其他方法使用Iterator来实现或者把remove放入到一个容器,在从容器遍历出要删除的内容。

心得体会

因为本人是留学生从2020年无法回到中国学习,只能通过老师发的视频和学习资料来学。要打开OO网站也需要使用VPN,比较麻烦。对OO作业觉得压力好大,但是还是得努力完成,遇到困难时可以问助教随时回复,很感谢他们。谢谢各位助教和老师对这一门课的指导。

Network 扩展

首先Advertiser、Producer、Customer都是属于Person的子类,ap、ar的方法不需要改变。
Advertiser需要发送的广告可以看成一种message,在addAdvertisement中添加,message类型为2,

/*@ public normal_behavior
      @ requires containsMessage(id) && getMessage(id).getType() == 2 &&
      @          getMessage(id).getPerson1() instanceof Advertiser;
      @ assignable messages;
      @ ensures !containsMessage(id) && messages.length == \old(messages.length) - 1 &&
      @         (\forall int i; 0 <= i && i < \old(messages.length) && \old(messages[i].getId()) != id;
      @         (\exists int j; 0 <= j && j < messages.length; messages[j].equals(\old(messages[i]))));
      @ ensures (\forall int i; 0 <= i && i < \old(getMessage(id).getPerson1().acquaintance[i]);
      @          \old(getMessage(id).getPerson1().acquaintance[i].getMessages().get(i+1) == \old(getMessage(id).getPerson1().acquaintance[i].getMessages().get(i)));
      @ ensures \old(getMessage(id).getPerson1().acquaintance[i].getMessages().get(0).equals(\old(getMessage(id)));
      @ ensures \old(getMessage(id)).getPerson1().acquaintance[i].getMessages().size() == \old(getMessage(id).getPerson1().acquaintance[i].getMessages().size()) + 1;
  	  @ also
      @ public exceptional_behavior
      @ signals (noAdvertisementIdException e) getMessage(id).getType() != 2;
      @ signals (MessageIdNotFoundException e) !containsMessage(id);
      @ signals (noAdvertiserException e) containsMessage(id) && getMessage(id).getType() == 2 &&
      @          !(getMessage(id).getPerson1() instanceof Advertiser);
      @*/   
public void sendAdvertisementMessage(int id) throws MessageIdNotFoundException, noAdvertisementException; //发送id对应的广告,如果消息type不为2(不是广告),就抛出对应异常,否则向与Advertiser有关系的人(除了producer之外)发送广告消息

Producer通过Advertiser销售产品,即通过addAdvertisement其中的person1为对应的Advertiser),message类型为2,且Producer与对应的Advertiser之间要有关系

/*@ public normal_behavior
      @ requires !(\exists int i; 0 <= i && i < messages.length; messages[i].equals(message)) &&
      @ message.getType() == 2 && (message.getPerson1() instanceof Advertiser);
      @ assignable messages;
      @ ensures messages.length == \old(messages.length) + 1;
      @ ensures (\forall int i; 0 <= i && i < \old(messages.length);
      @          (\exists int j; 0 <= j && j < messages.length; messages[j].equals(\old(messages[i]))));
      @ ensures (\exists int i; 0 <= i && i < messages.length; messages[i].equals(message));
      @ also
      @ public exceptional_behavior
      @ signals (EqualMessageIdException e) (\exists int i; 0 <= i && i < messages.length;
      @                                     messages[i].equals(message));
      @ signals (noAdvertiserException e) !(\exists int i; 0 <= i && i < messages.length;
      @                                     messages[i].equals(message)) && !(messages[i].getPerson1() 			  @										instanceof Advertiser);
      @*/
public void addAdvertisementMessage(Message message) throws EqualMessageIdException, EqualPersonIdException;

Customer购买产品直接通过Advertiser给相应Producer发一个购买消息,可分解成Customer添加购买消息、Advertiser向对应的Producer发送购买消息

/*@ public normal_behavior
      @ requires !(\exists int i; 0 <= i && i < messages.length; messages[i].equals(message)) &&
      @ message.getType() == 2 && (message.getPerson1() instanceof Advertiser);
      @ assignable messages;
      @ ensures messages.length == \old(messages.length) + 1;
      @ ensures (\forall int i; 0 <= i && i < \old(messages.length);
      @          (\exists int j; 0 <= j && j < messages.length; messages[j].equals(\old(messages[i]))));
      @ ensures (\exists int i; 0 <= i && i < messages.length; messages[i].equals(message));
      @ also
      @ public exceptional_behavior
      @ signals (EqualMessageIdException e) (\exists int i; 0 <= i && i < messages.length;
      @                                     messages[i].equals(message));
      @ signals (noAdvertiserException e) !(\exists int i; 0 <= i && i < messages.length;
      @                                     messages[i].equals(message)) && !(messages[i].getPerson1() 			  @										instanceof Advertiser);
      @*/
public void addSalesMessage(Message message) throws EqualMessageIdException, noAdvertiserException, noCustomerException, noProducerException; //添加购买消息

在Producer类可以查询自己卖到的多少东西

ensures \result == sales.length;
public void querySales()
posted @ 2022-05-31 17:51  quinna  阅读(27)  评论(0编辑  收藏  举报