真人视讯網站建設谘詢熱線:4000-669-688
因為專注,所以專業,鑫啟航是您值得信賴的合作夥伴!
當前位置:首頁 >> 常見問答

JAVA語言中網站出現問題該咋樣診斷

發布時間:2012-01-12   新聞來源:   瀏覽次數:
歡迎光臨診斷 Java 代碼,一個隔周更新的新專欄,著重討論和您日常編程工作有關的 Java 解決方案。本文為第一篇,介紹了錯誤模式的概念,一個非常有用的概念,它將提高您檢測和修正代碼中錯誤的能力。您會了解到一種最普遍的錯誤模式,這將為您開始識別和避免更高級的錯誤模式奠定基礎。
錯誤模式和它們為什麽有用
正如好的編程技能涉及很多設計模式(您可以在不同的程序上下文中組合和應用這些模式)的知識一樣,好的調試技能也涉及對 錯誤模式的一定了解。錯誤模式就是已發出的錯誤和程序中潛在的錯誤之間的重複出現的相互關係。這種概念對編程來說並不新鮮。醫生們在診斷疾病時依靠相似類型的相互關係。他們在實習期間通過和資格較老的醫生共同工作來學習這些。他們的教育就是集中在做這種診斷上的。相反,我們軟件工程師的教育是集中在過程設計和算法分析上的。這些技能固然重要,但是人們對調試過程的教育卻很少關注。相反,我們得自己去“拾起”這種技能。隨著極端編程的出現和它對單元測試的注重,這種做法已經開始改變了。但是頻繁的單元測試隻是解決了問題的一部分。一旦發現錯誤,就必須診斷和糾正它們。幸運的是,很多錯誤都遵循我們可以識別的幾種錯誤模式的其中一種。一旦您可以識別出這些錯誤模式,您就可以診斷出錯誤的原因並且更快地糾正它了。

錯誤模式與反模式有關,反模式是一次又一次被證明是失敗的公共軟件設計的模式。雖然反模式是設計模式,錯誤模式卻是與編程錯誤相關的錯誤的程序行為的模式。這與設計根本沒有關係,而是與編程和調試過程有關。

通過示例學習
為了說明錯誤模式後麵的思想,讓我們來考慮一種基本錯誤模式,編程新手(經常還有更高級的程序員)常常會遇到這種錯誤模式。在後麵的文章中,我們會談到更高級的錯誤模式。對每一種模式,我會討論將有助於把該模式的錯誤的發生控製到最少的編程原則(並非暗示所有的錯誤都是不遵循編程原則的結果;不管我們遵循多少原則,我們都會犯錯誤)。

為了分類起見,我會使用下麵的形式(從醫學上借用一些術語)來概括錯誤模式描述:

模式名稱
症狀
起因
治療方法和預防措施
Rogue Tile 模式
也許它是編程新手中最普遍的錯誤模式,起因是複製和粘貼一段代碼到程序的其它部分。有時,複製的一小部分因為功能上需求的略微不同而作了改動。不可避免地,錯誤在一個副本中被修正了,而在另一個副本中沒有被修正,這樣在錯誤症狀複發時就會讓您很頭疼。盡管大多數程序員很快就熟悉了這種錯誤模式,但他們中很少人采取適當的措施來將這種錯誤的出現控製到最少。您很容易就會偷懶不去思考而簡單地複製您認為已經可以運行的代碼。但是工作效率由於修正代碼而喪失,這是因為不加選擇的複製?粘貼操作很快降低了複製代碼帶來的任何工作效率。

我稱此為 Rogue Tile 模式是因為,一段代碼的各個副本可以被看成是分布在程序中的“tile”。由於不同副本中的代碼出現了差異,副本就變成了“rogue tile”。

症狀
這種錯誤的模式的最普遍症狀是,在您認為已經修正了問題以後,程序還繼續表現出錯誤的行為。

起因
為了理解這種情況發生的原因,我們來看看下麵的二元樹類層次結構:
public abstract class Tree {
}
public class Leaf extends Tree {
public Object value;
...
}
public class Branch extends Tree {
public Object value;
public Tree left;
public Tree right;
...
}

對於這些類要注意的第一件事就是,兩種具體類都包含 Object 類型的 value 字段。如果您決定稍後讓樹包含,比如說,Interger,您也許會忘記更新其中的一個字段聲明。如果程序的其它部分需要這些字段是 Interger 的話,程序就很可能不會編譯。您或許記得您改變了其中一個類的 value 字段的類型,卻忽略了一個事實,就是您沒有在其它類中作相應的改變。

一些預防措施
當然,這個示例所示的錯誤是編程新手可以很快學會通過分解出公共代碼來避免的。在本例中,字段聲明應該移到 Tree 類中。它的兩個子類就會繼承這個字段,而且對字段聲明的任何改變都隻需要在一個地方出現。

繼續看這個示例,我們可能還會編寫在一個 Tree 中相加和相乘所有節點的方法。為了簡單起見,我將以遞歸的方式來編寫這些方法。

// in class Tree:
public abstract int add();
public abstract int multiply();
// in class Branch:
public int add() {
return this.value.intValue() + left.add() + right.add();
}
public int multiply() {
return this.value.intValue() * left.multiply() + right.multiply();
}
// in class Leaf:
public int add() { return this.value.intValue(); }
public int multiply() { return this.value.intValue(); }
請注意我在 multiply 方法中為 Branch 類引入的錯誤:我沒有用第三項去乘,而是加了它。錯誤發生了,因為我通過複製 add 方法中的代碼並作輕微(但不完全)的改動創建了 multiply 方法。這種錯誤非常隱蔽,因為調用 multiply 方法永遠不會發出錯誤信號。事實上,在很多情況下,它會返回一個看上去完全合理的結果。

就象以前一樣,我們可以通過分解出公共代碼來將這種錯誤控製到最少。在這種情況下,我們可以編寫一個單獨的方法,它在 Tree 上累計一個運算符(作為一個參數傳送)。我們可以使用一種被稱為公共模式的設計模式(不是錯誤模式!)在對象中封裝這個運算符。

public abstract class Operator {
public abstract int apply(int l, int r);
}

public class Adder extends Operator {
public int apply(int l, int r) {
return l + r;
}
}

public class Multiplier extends Operator {
public int apply(int l, int r) {
return l * r;
}
}

然後我們就可以如下麵的代碼所示在我們的 Tree 類層次結構中改變這個方法:

// in class Tree:

public abstract int accumulate(Operator o);

public int add() {
return this.accumulate(new Adder());
}
public int multiply() {
return this.accumulate(new Multiplier());
}
// in class Leaf:

public int accumulate(Operator o) {
return value.intValue();
}
in class Branch:
public int accumulate(Operator o) {
return o.apply(this.value.intValue(),
o.apply(left.accumulate(o),
right.accumulate(o)));
}

通過分解出公共代碼,我們消除了在 add 和 multiply 方法正文中出現複製?粘貼錯誤的可能性。另外,請注意我們不再需要為 Tree 的每一個子類編寫單獨的 add 和 multiply 方法了。

分解出公共代碼是一個很好的習慣,但它並不適用於所有的情況。比如說,Java 類型係統的簡單性經常迫使我們在精確類型檢驗和保持對程序的每個不同的功能性元素的單點控製(請參閱參考資料,閱讀我寫的關於 NextGen 的文章)之間作出選擇。正因為這個,Rogue Tile 模式是所有開發人員必須一直努力以控製到最少的一種錯誤類型。
下一篇內容是什麽?
簡而言之,這是我們的第一個錯誤模式。您可能想把它剪下來釘在您的公告牌上作為提醒。
模式:Rogue Tile
症狀:代碼好像表現出前麵糾正過的錯誤依然存在。
起因:複製?粘貼代碼片段的至少一個副本還包含在其它副本中已經修正了的錯誤。
治療和預防措施:如果可能,分解出公共代碼;否則就對其進行更新。避免複製和粘貼代碼。
在我的下一篇文章中,我會探究 Java 代碼中出現過的其它一些普遍的錯誤模式。我們將特別看一下作為空指針異常而出現的錯誤模式,並討論如何將它們的出現次數控製到最少。
參考資料
訪問模式主頁,這是一個介紹設計模式以及如何使用它們的優秀主頁。
反模式主頁提供了關於該主題的書籍的信息和鏈接。
如果您還沒有這麽做,請查閱極端編程,一個快速開發簡潔的、健壯的軟件的強大的新方法。
然後下載 JUnit 並立刻開始單元測試。
Eric Allen 的關於 NextGen(Java 的一個運行時泛型類型的擴展)的文章說明了一個更加強大的類型係統是怎樣幫助減輕存在於分解公共代碼和使用類型係統在編譯期間捕捉錯誤的兩個目標之間的一些壓力的。
致電 4000-669-688
全國7x24小時服務熱線
在線谘詢
每工作日 9:00-17:30
點擊進入>>
預約鑫啟航
為您提供一對一解決方案
點擊進入>>
訪問官方微博
進入官方微博平台
點擊進入>>
公司旗下網站
進入鑫啟航旗下網站
點擊進入>>
公司服務:網站營銷策劃 網站製作  營銷型網站 企業管理軟件 企業網絡營銷方案 真人视讯網站建設 真人视讯網站優化 真人视讯網絡營銷  
Copyright 2010-2020 
 All Rights Reserved  豫ICP備11017872號 地址:河南省真人视讯市金水區民航路19號企業壹號613室
网站地图:sitemap