面向对象第三单元个人总结
第三单元总结
1.自测过程中测试数据的准备
在本单元中,我主要通过白盒测试来准备测试数据,即通过阅读JML规格,构造边界数据进行测试,以保证程序正确性。
2.架构设计、图模型构建和维护策略
主要的框架其实都已经被规定了,简单说一下图模型的构建以及维护的策略
各种变量主要在Network里面动态维护:(以及一些中间变量,如树分支的储存)
为了防止MyNetwork类内方法太多,过于臃肿,我还建立了MyTool类储存一些联系较少的方法:
qci和qbs都是用的并查集,比起dfs时间复杂度降低了;
qlc使用dijkstra算法,但排序上我的代码性能较差。
动态维护:
主要就是各个树内的节点、并查集的connect
数组以及求最短路径时各两点间的最短距离
3.代码实现出现的性能问题和修复情况
3.1第一次作业
在第一次作业中,代码出现的问题主要是我没有正确理解qbs
命令的jml
规格含义,导致正确性出现很大问题,虽过了中测,但强测一塌糊涂,想来这是我没有充分测试、与同学交流的缘故,修复时修改代码使其重新求取正确结果——树的个数,便完成了修复。
3.2第二次作业
第二次作业性能难点来自于两条指令,qgvs
和qlc
。
但我出问题的指令依旧是qbs
,原因在于每次执行指令时都要重新查询计算一次,导致性能大大降低,修复时建立hashmap
以储存每个树各自节点,且可以直接得到qbs
结果。
3.3第三次作业
第三次作业的性能问题主要来自send_indirect_message
指令,这条指令对应着最短距离算法。
但我出问题的指令依旧是qgvs
,以及einf
错误类型输出顺序问题导致的错误类型输出错误。qgvs
原因在于没有实现MyGroup
类内各项指标的动态变化,致使每次调用指令都要再进行一次静态计算,大大增加CPU时间。修复时,调整了错误的输出顺序,并进行动态调整group
的相关指标。
4.Network扩展
假设出现了几种不同的Person
-
Advertiser:持续向外发送产品广告
-
Producer:产品生产商,通过Advertiser来销售产品
-
Customer:消费者,会关注广告并选择和自己偏好匹配的产品来购买 -- 所谓购买,就是直接通过Advertiser给相应Producer发一个购买消息
-
Person:吃瓜群众,不发广告,不买东西,不卖东西
如此Network可以支持市场营销,并能查询某种商品的销售额和销售路径等 请讨论如何对Network扩展,给出相关接口方法,并选择3个核心业务功能的接口方法撰写JML规格。
-
Advertiser Producer Customer 都继承了类Person
-
增加类Product,属性包括id,price,Producer
-
Advertiser只对Customer打广告,并发送给所有的Customer
-
Advertiser有一定数量的Products,并通过Product向相应的Producer发送购买消息
选择了设置用户偏好,购买商品,打广告,撰写了JML规格;
设置用户偏好
/*@ public normal_behavior @ requires (\exists int i; 0 <= i && i < people.length; people[i].getId() == Personid && people[i] instanceof Customer) && (\exists int i; 0 <= i && i<= products.length;products[i].getId() == ProductId); @ assignable getPerson(personId).preferences; @ ensures (\forall Product i;\old(getPerson(PersonId).prefer(i));getPerson(PersonId).prefer(i)); @ ensures getPerson(personId).prefer(ProductId); @ also @ public exceptional_behavior @ signals (PersonIdNotFoundException e) !(\exists int i; 0 <= i && i < people.length; @ people[i].getId() == id && people[i] instanceof Customer); @ signals (ProductIdNotFoundException e) !(\exists int i; 0 <= i && i < products.length; @ products[i].getId() == ProductId); @*/ public void setPreference(int PersonId, int ProductId) throw PersonIdNotFoundException,ProductIdNotFoundException;
customer通过advertiser购买商品
/*@ public normal_behavior @ requires (\exists int i; 0 <= i && i < people.length; people[i].getId() == CustomerId && people[i] instanceof Customer) && (\exists int i; 0 <= i && i<= people.length; people[i].getId() == AdvertiserId && people[i] instanceof Advertiser) && (\exists int i; 0 <= i && i<= products.length;products[i].getId() == ProductId); @ ensures getPerson(CustomerId).money = \old(getPerson(customerId).mondy) - getProduct(ProductId).getPrice(); @ ensures getPerson(AdvertiserId).getRemaining(ProductId) = \old(\getPerson(AdvertiserId).getRemaining(ProductId)) - 1; @ also @ public exceptional_behavior @ signals (PersonIdNotFoundException e) !(\exists int i; 0 <= i && i < people.length; @ people[i].getId() == id && people[i] instanceof CustomerId); @ signals (PersonIdNotFoundException e) !(\exists int i; 0 <= i && i < people.length; @ people[i].getId() == id && people[i] instanceof AdvertiserId); @ signals (ProductIdNotFoundException e) !(\exists int i; 0 <= i && i < products.length; @ products[i].getId() == ProductId); @*/ public void purchase(int AdvertiserId,int CustomerId,int ProductId) throw PersonIdNotFoundException,ProductIdNotFoundException;
advertiser投放广告
/*@ public normal_behavior @ requires (\exists int i; 0 <= i && i < people.length; people[i].getId() == advertiserId && people[i] instanceof Advertiser) && (\exists int i; 0 <= i && i<= messages.length;products[i].getId() == adMsgId && products[i] instanceof adMessage); @ assignable messages; @ ensures !containsMessage(adMsgId) && messages.length == \old(messages.length) - 1 && @ (\forall int i; 0 <= i && i < \old(messages.length) && \old(messages[i].getId()) != adMsgId; @ (\exists int j; 0 <= j && j < messages.length; messages[j].equals(\old(messages[i])))); @ ensures (\forall int i; 0<= i && i < people.length; people[i] instanceof Customer ; (\forall int j; 0 <= j && j < \old(getPerson(i).getMessages().size()); @ getPerson(i).getMessages().get(j+1) == \old(getPerson(i).getMessages().get(i)) && @ getPerson(i).getMessages().get(0) == \old(getMessage(adMsgId)) && @ \old(getPerson(i).getMessages().size() == \old(getPerson(i).getMessages().size()) + 1)); @ also @ public exceptional_behavior @ signals (PersonIdNotFoundException e) !(\exists int i; 0 <= i && i < people.length; @ people[i].getId() == id && people[i] instanceof Advertiser); @*/ public void advertise(int advertiserId,int adMsgId) throw PersonIdNotFoundException;
5.心得体会