OO - 第三單元總結
OO第三單元總結
要求
第一次作業總結
分析
-
在本單元我們的任務為需要完成的任務為通過一個實現簡單社交關係的模擬和查詢的例子以此達到學習入門級
JML
規格理解與程式碼實現的能力 -
本次作業只需要讀懂程式碼中的
JML
表示語言,並且按照其中的要求編寫好程式碼即可,由於客戶需求基本都已經表述的很明白了,所以留給你的實現空間挺少的 -
JML
表示語言中的虛擬碼只是給你實現的一種參考,僅僅是規格層次的描述,實際上並不需要嚴格按照其程式碼編寫,只要你最後的程式碼能滿足條件即可
基本思路
-
雖然這次的程式碼框架和方法已經確定,我們只需要完成的任務只是程式碼填空,但分析清楚程式碼的功能和實現邏輯還是很有必要的
-
本次作業為實現簡單社交關係的模擬和查詢,核心為
MyPerson
類,管理此類的資料結構分別為實現了對應介面的MyGroup
類以及MyNetWork
類,三者狗證了本次作業的基本框架,在這三類中實現了所需功能對應的各種方法 -
本次作業新增了異常處理機制,在
JML
表示語言中表明瞭在方法中處於何種情況下需要丟擲哪一種異常,並且實現異常的計數和列印的功能
具體實現
-
人物介面
Person
- 重寫
equal
和compareTo
方法 - 編寫
id
和name
和age
的Getter
方法 -
isLinked
: 檢視兩人物之間是否存在關係 -
queryValue
- 重寫
-
人物類
MyPerson
-
acquaintance
: 儲存與該人有關係的人 -
value
: 儲存與人的權重,與acquaintance
的下標相對應 -
link
: 使兩人建立關係的方法
-
-
分組介面
Group
-
addPerson
,delPerson
: 對分組中的人的增加與刪除 -
hasPerson
: 查詢此分組是否存在該人 -
getValueSum
: 返回與此人有關係所有人的權重的總和 -
getAgeMean
,getAgeVar
: 獲得該分組的所有人年齡的平均值,方差 -
getSize
: 獲得該分組的大小 -
getId
: 獲得該分組的id -
分組類
MyGroup
-
people
儲存所有該分組中的人 -
網路介面
Network
-
contains
: 此網路是否包含此人 -
getPerson
: 根據id
獲取對應的人物 -
addPerson
: 向網路中增加人物 -
addRelation
: 讓兩個人產生關係 -
queryValue
: 獲取兩個人之間關係的權重 -
queryPeople
: 獲取網路中人數的總和 -
isCircle
: 判斷是否可以通過此網路中的人來使兩個人之間‘間接’建立關係 -
queryBlockSum
: 獲取關係網的數量 -
addGroup
: 向網路中增加分組 -
getGroup
: 根據id
獲取對應分組 -
addToGroup
: 將人物加入到分組中 -
delFromGroup
: 將人物移除出分組
-
-
網路類
MyNetwork
-
getRoot
: 並查集資料結構,獲取一個人物的根結點 -
parent
: 並查集資料結構,標記一個人物的父結點 -
people
: 網路中儲存人物 -
groups
: 網路中儲存分組
-
-
人物Id重複抽象類 & 任務Id重複類
PersonIdNotFoundException & MyPersonIdNotFoundException
-
分組Id重複抽象類 & 分組Id重複類
EqualPersonIdException & MyEqualPersonIdException
-
未具有關係抽象類 & 未具有關係類
RelationNotFoundException & MyRelationNotFoundException
-
關係已存在抽象類 & 關係已存在類
EqualRelationException & MyEqualRelationException
-
未找到分組Id抽象類 & 未找到分組Id類
GroupIdNotFoundException & MyGroupIdNotFoundException
-
分組Id相同抽象類 & 分組Id相同類
EqualGroupIdException & MyEqualGroupIdException
關鍵演算法
並查集
基於度量的程式結構分析
-
程式碼規模分析
-
方法複雜度分析(部分)
-
類複雜度分析
第二次作業總結
分析
-
本次作業在上一次作業的基礎之上新增了
Message
類,並且新增了關於其屬性和其所在網路屬性的一些查詢方法 -
根據第一次作業留下的可拓展介面進行迭代開發(虛假的迭代開發:根據官方包所給
Jml
註釋填空,莫得感情的填空機器)
需求變更
新增內容:
-
Message
類 -
多種查詢方法
-
兩種異常處理函式
資料限制變更:
-
最大指令數:
1000
\(\rightarrow\)10000
-
add_person
指令條數不超過2500
-
query_circle
指令條數不超過333
-
add_group
指令條數不超過25
-
query_least_connection
指令條數不超過100
-
add_message
指令:保證type
為0
或1
,socialValue
值在[-1000,1000]
中
迭代開發
新增:
-
訊息介面
Message
- 重寫
equal
方法 - 編寫
id
和type
和Person1
和Person2
和name
和group
的get
方法
- 重寫
-
訊息類
MyMessage
-
socialValue
: 儲存兩個人之間關係權重
-
修改:
-
人物介面
Person
-
socialValue
的add
和get
方法 -
Money
的add
和get
方法 -
Messages
的獲取方法 -
receivedMessages
的獲取方法
-
-
人物類
MyPerson
-
Messages
: 儲存訊息 -
Money
: 儲存現有錢的數量 -
socialValue
: 儲存活動值
-
-
網路介面
Network
-
query_group_people_sum
: 獲取組內人物數目 -
query_group_value_sum
: 獲取組內人物權重的總和 -
query_group_age_var
: 獲取組內人物年齡的方差 -
add_message
: 加入訊息 -
send_message
: 給某人傳送訊息 -
query_social_value
: 獲取某人的活躍度 -
query_received_messages
: 獲取某人接受到的所有訊息 -
query_least_connection
: 獲取最短連線人的通路
-
-
網路類
MyNetwork
-
messages
: 網路中儲存訊息 -
beginLines
&endLines
: 儲存有關係的二人的結點 -
values
: 儲存兩人關係的權重
-
-
訊息Id重複抽象類 & 訊息Id重複類
EqualMessageIdException & MyEqualMessageIdException
-
未找到訊息Id抽象類 & 未找到訊息Id類
MessageIdNotFoundException & MyMessageIdNotFoundException
關鍵演算法
最小生成樹演算法
基於度量的程式結構分析
-
程式碼規模分析
-
方法複雜度分析(部分)
-
類複雜度分析
第三次作業總結
分析
-
本次作業在上一次作業的基礎之上新增了
Message
類的各個子類:EmojiMessage
類、NoticeMessage
類、RedEnvelopeMessage
類,並且新增了關於其屬性和其所在網路屬性的一些查詢方法 -
根據第二次作業留下的可拓展介面進行迭代開發(虛假的迭代開發:根據官方包所給
Jml
註釋填空,莫得感情的填空機器)
需求變更
新增內容:
-
EmojiMessage
類 -
NoticeMessage
類 -
RedEnvelopeMessage
類 -
多種查詢方法
-
兩種異常處理函式
資料限制變更:
-
add_person
指令條數: 不超過2500
\(\rightarrow\) 不超過5000
-
send_indirect_message
指令條數不超過1000
-
emoji_id(int)
值在[0,10000]
中 -
add_message
,add_red_envelope_message
,add_notice_message
,add_emoji_message
指令:保證type
為0
或1
,socialValue(int)
值在[-1000,1000]
中,money(int)
值在[0,200]
中,string(String)
長度不超過100
迭代開發
新增:
-
表情訊息介面
EmojiMessage
-
socialValue
和get
方法
-
-
表情訊息類
MyEmojiMessage
-
公告訊息介面
NoticeMessage
- 訊息內容
String
的get
方法
- 訊息內容
-
公告訊息類
MyNoticeMessage
-
紅包訊息介面
RedEnvelopeMessage
-
Money
的get
方法
-
-
紅包訊息類
MyRedEnvelopeMessage
-
最小堆類
MinHeap
-
add
方法 : 向最小堆中增加一個人及其權重 -
get
&getDist
方法 : 從最小堆中取一個人並且獲得其權重
-
修改:
-
網路介面
Network
-
add_red_envelope_message
: 增加紅包訊息 -
add_notice_message
: 增加公告訊息 -
clear_notices
: 清除公告訊息 -
add_emoji_message
: 增加表情訊息 -
store_emoji_id
: 增加新的表情 -
query_popularity
: 查詢表情熱度 -
delete_cold_emoji
: 刪除熱度低的表情 -
query_money
: 查詢某人錢數 -
send_indirect_message
: 傳送間接訊息
-
-
網路類
MyNetwork
&MyNetWork2
MyNetwork2
類的建立純屬MyNetWork
類超500
行了……-
emojiIdList
: 儲存表情的列表 -
emijiHeatList
: 儲存表情的熱度 -
totalPath
: 儲存在計算最短路中已經求得最短路的結點 -
graph
: 儲存人與人之間關係及權重的圖
-
-
表情訊息Id重複抽象類 & 表情訊息Id重複類
EmojiIdNotFoundException & MyEmojiIdNotFoundException
-
未找到表情訊息Id抽象類 & 未找到表情訊息Id類
EqualEmojiIdException & MyEqualEmojiIdException
關鍵演算法
最短路徑演算法
基於度量的程式結構分析
-
程式碼規模分析
-
方法複雜度分析(部分)
-
類複雜度分析(部分)
分析在本單元自測過程中如何利用JML規格來準備測試資料
- 閱讀
JML
規格程式碼,依據規格的不同邊界條件特定的構造相應資料以驗證正確性,並且進行覆蓋測試以及隨機測試來進一步確保我們程式的正確性;進一步可以構造資料以進行壓力測試來確保我們程式碼的效能的完備
梳理本單元的架構設計,分析自己的圖模型構建和維護策略
-
架構設計(好像官方程式碼已經把架構定死了):每一個類都有對應的方法,對應問題中的一類操作
-
圖構建及維護策略:使用了鄰接表來儲存關係網中的圖,使用了
Java
自帶的ArrayList
以及HashMap
容器增加程式碼的可讀性和維護性
按照作業分析程式碼實現出現的效能問題和修復情況
- 第二次作業時,由於沒有用圖儲存結點而是採用了遍歷尋找節點的方式,導致在尋找最小生成樹時執行時間超時,而後使用圖儲存結點並在圖中尋找,修復了此問題
請針對下頁ppt內容對Network進行擴充套件,並給出相應的JML規格
-
PPT
內容: -
假設出現了幾種不同的
Person
-
Advertiser
:持續向外傳送產品廣告 -
Producer
:產品生產商,通過Advertiser
來銷售產品 -
Customer
:消費者,會關注廣告並選擇和自己偏好匹配的產品來購買 -- 所謂購買,就是直接通過Advertiser
給相應Producer
發一個購買訊息 -
Person
:吃瓜群眾,不發廣告,不買東西,不賣東西 - 如此
Network
可以支援市場營銷,並能查詢某種商品的銷售額和銷售路徑等 請討論如何對Network
擴充套件,給出相關介面方法,並選擇3
個 核心業務 功能的介面方法撰寫JML
規格(借鑑所總結的JML
規格模式)
-
-
生產產品:
/*@ public normal_behavior
@ requires !(\exists int i; 0 <= i && i < getPerson(personId).products.length; getPerson(personId).products[i].getId() == id);
@ assignable getPerson(personId).products ;
@ ensures (\forall int i; 0 <= i && i < \old(getPerson(personId).products.length) ;
@ getPerson(personId).products[i].getId() == id );
@ ensures getPerson(personId).products.length == \old(getPerson(personId).products.length) + 1 ;
@ ensures getPerson(personId).hasProduct(id);
@ also
@ public exceptional_behavior
@ signals (EqualAdvertiseIdException e) (\exists int i; 0 <= i && i < getPerson(personId).products.length;
@ getPerson(personId).products[i].getId() == id) ;
@*/
public void addProduct(String personId, Advertisement id);
- 購買
/*@ public normal_behavior
@ requires (\exists int i; 0 <= i && i < advertisers.length;
@ advertisers.get(i).equals(advertiser));
@ ensures money == \old(money) - product.getValue();
@ ensures production.length == \old(production).length + 1;
@ ensures (\exists int i; 0 <= i && i < production.length;
@ production.get(i).equals(product));
@*/
public /*@ pure @*/ void buy(Advertiser advertiser, Product product);
- 給予生產建議
/* @ public normal_behavior
@ requires (\exists int i; 0 <= i && i < customers.length;
@ customers.get(i).equals(customer));
@ ensures customer.getAdvertisements.length ==
@ \old(customer.getAdvertisements).length + 1;
@ ensures (\exists int i; 0 <= i && i < customer.getAdvertisements.length
@ customer.getAdvertisements.get(i).equals(advertisement));
@*/
public /*@ pure @*/ void sendAdvertisement(Customer customer, Advertisement advertisement);
本單元學習體會
- 本單元學習了由契約式設計而延伸出來的
JML
程式碼,契約式設計是一種基於信任機制權利義務均衡機制的設計方法學,JML
源自於契約式設計的需要,並掌握了基於JML
的規格模式及基於JML
規格的測試與驗證,受益匪淺