OO9-11总结
規(guī)格化設(shè)計(jì)的大致發(fā)展歷史
1960年代末—1970年代初,出現(xiàn)軟件危機(jī):對(duì)軟件系統(tǒng)的大量需求與軟件的研制周期長(zhǎng),可靠性差,維護(hù)困難的現(xiàn)實(shí)情況形成矛盾。于是人們希望編寫出的程序結(jié)構(gòu)清晰、易閱讀、易修改、易驗(yàn)證,即得到好結(jié)構(gòu)的程序。1968年,北大西洋公約組織召開第一次軟件工程會(huì)議,分析了危機(jī)的局面,研究了問題的根源,第一次提出了用工程學(xué)的辦法解決軟件研制和生產(chǎn)的問題。
與此同時(shí),許多學(xué)者也從結(jié)構(gòu)化程序設(shè)計(jì)、程序正確性驗(yàn)證等方面展開了規(guī)格化設(shè)計(jì)的研究。Dijkstra 提出了“GOTO是有害的”,希望通過程序的靜態(tài)結(jié)構(gòu)的良好性保證程序的動(dòng)態(tài)運(yùn)行的正確性。Hoare提出了基于“前置后置條件”的接口規(guī)格方法。D.Gries綜合了以謂詞演算為基礎(chǔ)的證明系統(tǒng),首次把程序設(shè)計(jì)從經(jīng)驗(yàn)、技術(shù)升華為科學(xué)。
規(guī)格化設(shè)計(jì)帶來了許多好處。它使得軟件開發(fā)過程變得更成熟,能更好地保證軟件質(zhì)量。而且使得團(tuán)隊(duì)協(xié)作開發(fā)更加可行,分工更為明確。所以人們非常重視。
規(guī)格bug
?
| ? | Bug數(shù) | 代碼長(zhǎng)度 |
| Requires不完整 | 2 | 22(write) |
| ? | ? | 1(addMap) |
| Effects不完整 | 1 | 3(SafeFile) |
產(chǎn)生原因:
Requires不完整的兩個(gè)錯(cuò)誤原因:其一是在寫被改變的變量的時(shí)候,類變量一多,混雜在臨時(shí)變量之間就容易被忘記。第二是對(duì)參數(shù)要求的時(shí)候容易想不清楚。比如說存地圖時(shí),在輸入處理環(huán)節(jié)就已經(jīng)保證不會(huì)傳入非法的參數(shù),所以在存的這一步我沒有對(duì)傳入變量進(jìn)行要求,但事實(shí)上應(yīng)該要求的。我們不能提前預(yù)知到前方已經(jīng)做過處理了,因此要施加我們的要求,好讓前方的處理按照我們的規(guī)格進(jìn)行處理。
Effects不完整是因?yàn)橥藢憭伋霎惓!Mㄟ^這幾次互策 互測(cè),及OO上機(jī)代碼,我發(fā)現(xiàn)大家都有著很好的異常處理,不像我想到了就給方法加個(gè)try catch。他們的異常處理很方便定位錯(cuò)誤位置,且邏輯性很好,學(xué)到了。
前置條件不好的寫法
公開處刑1
public void runLess(Point from, Point to){/** @REQUIRES: 起點(diǎn)from,終點(diǎn)to……*/……from.method();to.method();…… }用自然語言來寫前置條件,為了表達(dá)同樣的意思需要更多筆墨。此處的Requires需對(duì)from,to進(jìn)行約束,因?yàn)楹瘮?shù)體內(nèi)部運(yùn)用了對(duì)象的方法。所以寫成下面這樣更簡(jiǎn)潔更明確。
/** @REQUIRES: from != null && to != null;公開處刑2
public synchronized boolean judge(Passenger p) {/**@REQUIRES: p!=null && 0<=p.getCurrentX<80 && 0<=p.getCurrentY<80&& 0<=p.getDestinationX<80 && 0<=p.getDestinationY<80;* @THREAD_EFFECTS: \locked();*/ }
這和我之前想不清楚的地方一樣:我要對(duì)這個(gè)對(duì)象約束多深?比如:如果傳入?yún)?shù)是一個(gè)ArrayList,我是否在保證其不為null的情況下還要保證內(nèi)部元素不為null;如果是ArrayList<Taxi>的話是否還要檢查元素為Taxi類型,是否還要檢查Taxi的內(nèi)部參數(shù)滿足要求。現(xiàn)在我覺得不需要約束這么多,應(yīng)交給別的地方來保證這些。例如在Passenger的構(gòu)造方法中對(duì)乘客的坐標(biāo)進(jìn)行約束。所以此處寫?p != null;?就夠了。
沒法寫5個(gè)案例,因?yàn)槲业那爸脳l件不是在約束數(shù)字范圍就是在限制不能為空。
后置條件不好的寫法
?公開處刑1
public synchronized boolean isSame(Passenger p) {/**@REQUIRES: requestList != null && p != null;* @EFFECTS :* \result == requestList.contains(p);* @THREAD_EFFECTS: \locked();*/遍歷requestList并根據(jù)Passenger的實(shí)例變量來判斷是否同質(zhì)}這個(gè)寫的不好的地方在于同質(zhì)的話,就存在一個(gè)和p在時(shí)間、當(dāng)前坐標(biāo)、將要去的地方完全一樣的對(duì)象,但這個(gè)對(duì)象和我傳入的對(duì)象并不是一個(gè)對(duì)象,所以這種寫法不好。但感覺很難改進(jìn),只能自己寫一個(gè)contains的方法來保證這個(gè)Effects。
公開處刑2
public static void main(String[] args) {/** @EFFECTS: * 啟動(dòng)xx線程,啟動(dòng)xx線程,啟動(dòng)xx線程*/Effects應(yīng)該描述方法結(jié)束后系統(tǒng)的變化。在main方法開始前,這些線程還未出生,main結(jié)束的時(shí)候又一波帶走了他們,所以main的Effects內(nèi)只需寫對(duì)類變量的改變就行了。
*如果一個(gè)方法調(diào)用了很多別的方法,我要對(duì)這個(gè)方法的效果描述到多深是一個(gè)困擾著我的問題。
?按照作業(yè)分析被報(bào)的功能bug與規(guī)格bug在方法上的聚集關(guān)系
沒有什么關(guān)系。
因?yàn)椴皇窍葘懸?guī)格再寫功能的。
規(guī)格出問題的功能都沒問題。反之亦然。
歸納自己在設(shè)計(jì)規(guī)格和撰寫規(guī)格的基本思路和體會(huì)
基本思路就是關(guān)注外部環(huán)境,關(guān)注方法結(jié)束后的思想吧。
? 體會(huì)是規(guī)格蠻重要的,但是現(xiàn)在還不太能體會(huì)到,反而不如讀代碼快。
最不能理解的是測(cè)試者保證的地方又允許測(cè)試者不保證來測(cè)試,還不如不說。該保證的地方不保證得到錯(cuò)誤情況難道不是當(dāng)然的嗎?
其他
這三次體驗(yàn)很不好,很影響我心情,遇到了好的測(cè)試者、被測(cè)試者,但所有的好心情也敵不過一次壞心情。尤其是最后一次吧,終于見到了OO課程被大家詬病的問題了。但他人惡意來面對(duì)我,我如果還將惡意傳遞出去,豈不是也成了惡人了嗎。有什么必要呢,分?jǐn)?shù)拿走便是了,我應(yīng)該關(guān)注如何把代碼寫的更嚴(yán)密,挑不出瑕疵,關(guān)掉網(wǎng)站頁面。
轉(zhuǎn)載于:https://www.cnblogs.com/AAO972/p/9105226.html
總結(jié)
- 上一篇: 由event target引发的关于事件
- 下一篇: [转][linux]简单的linux下的