正確性正確性是指軟體按照需求正確執行任務的能力。這裡“正確性”的語義涵蓋了“精確性”。正確性無疑是第一重要的軟體品質屬性。如果軟體運行不正確,將會給使用者造成不便甚至損失。技術評審和測試的第一關都是檢查工作成果的正確性。正確性說起來容易做起來難。因為從“需求開發”到“系統設計”再到“實現”,任何一個環節出現差錯都會降低正確性。機器不會主動欺騙人,軟體運行出錯通常都是人造成的,所以不要找借口埋怨機器有毛病。開發任何軟體,開發人員都要為“正確”兩字竭盡全力。
健壯性健壯性是指在異常情況下,軟體能夠正常啟動並執行能力。正確性與健壯性的區別是:前者描述軟體在需求範圍之內的行為,而後者描述軟體在需求範圍之外的行為。可是正常情況與異常情況並不容易區分,開發人員往往要麼沒想到異常情況,要麼把異常情況錯當成正常情況而不做處理,結果降低了健壯性。使用者才不管正確性與健壯性的區別,反正軟體出了差錯都是開發方的錯。所以提高軟體的健壯性也是開發人員的義務。健壯性有兩層含義:一是容錯能力,二是恢複能力。容錯是指發生異常情況時系統不出錯誤的能力,對於應用於航空航天、武器、金融等領域的這類高風險系統,容錯設計非常重要。容錯是非常健壯的意思,比如UNIX的容錯能力很強,很難使系統出問題。而恢複則是指軟體發生錯誤後(不論死活)重新運行時,能否恢複到沒有發生錯誤前的狀態的能力。從語義上理解,恢複不及容錯那麼健壯。例如,某人挨了壞蛋一頓拳腳,特別健壯的人一點事都沒有,表示有容錯能力;比較健壯的人,雖然被打倒在地,過了一會還能爬起來,除了皮肉之痛外倒也不用去醫院,表示恢複能力比較強;而虛弱的人可能短期恢複不過來,得在病床上躺很久。恢複能力是很有價值的。Microsoft公司早期的視窗系統,如Windows 3.x和Windows 9x,動不動就死機,其容錯性的確比較差。但它們的恢複能力還不錯,機器重新啟動後一般都能正常運行,看在這個份上,人們也願意將就著用。
可靠性可靠性不同於正確性和健壯性,軟體可靠性問題通常是由於設計中沒有料到的異常和測試中沒有暴露的代碼缺陷引起的。可靠性是一個與時間相關的屬性,指的是在一定環境下,在一定的時間段內,程式不出現故障的機率,因此是一個統計量,通常用
平均無故障時間(MTTF, mean-time to fault)來衡量。可靠性本來是硬體領域的術語。比如某個電子裝置在剛開始工作時挺好的,但由於器件在工作中其物理性質會發生變化(如發熱、老化等),慢慢地系統的功能或效能就會失常。所以一個從設計到生產完全正確的硬體系統,在工作中未必就是可靠的。人們有時把可靠性叫做穩定性。軟體在運行時不會發生物理性質的變化,人們常認為如果軟體的某個功能是正確的,那麼它一輩子都是正確的。可是我們無法對軟體進行徹底的測試,無法根除軟體中潛在的錯誤。平時軟體運行得好好的,說不準哪一天就不正常了,如有千年等一回的“千年蟲”問題、司空見慣的“記憶體泄露”問題、“誤差累積”問題,等等。因此把可靠性引入軟體領域是很有意義的。軟體可靠性分析通常採用統計方法,遺憾的是目前可供第一線開發人員使用的成果很少見,大多數文章限於理論研究。我曾買了一本關於軟體可靠性的著作,此書充滿了數學公式,實在難以看懂,更不知道怎樣應用。請寬恕我的愚昧,我把此“天書”給“供養”起來,沒敢用筆畫一處記號。口語中的可靠性含義寬泛,幾乎囊括了正確性、健壯性。只要人們發現系統有毛病,便歸結為可靠性差。從專業角度講,這種說法是不對的,可是我們並不能要求所有的人都準確地把握品質屬性的含義。有必要搞清楚“故障”和“錯誤”這兩個容易混淆的概念。在《現代英漢詞典》裡,“故障(Fault)”一詞的定義是:使裝置、組件或元件不能按所要求的方式啟動並執行一種意外情況,可能是物理的也可能是邏輯的。那些潛伏在代碼中的錯誤往往是不明顯的,之所以在測試的時候沒有暴露,是因為測試時的環境和條件不足以使之暴露,更何況我們無法對代碼進行最徹底的測試。由此可見,故障是在經過日積月累,滿足了一定的條件之後才出現的。例如,“千年蟲”問題,“記憶體流失(吃記憶體)”導致記憶體耗盡,“誤差累積”導致計算錯誤進而導致連鎖反應,“效能開銷累積”導致效能顯著下降,等等。因此,故障通常都是不可預料的、災難性的。“錯誤”的含義要廣泛得多,例如,語法錯誤、語義錯誤、檔案開啟失敗、動態儲存裝置分配失敗等。一般說來,程式錯誤是可以預料的,因此可以預設錯誤處理程式,運行時這些錯誤一旦發生,就可以調用錯誤處理程式把它幹掉,程式還可以繼續運行。因此,錯誤的結果一般來說不是災難性的。
效能效能通常是指軟體的“時間—空間”效率,而不僅是指軟體的運行速度。人們總希望軟體的運行速度快些,並且佔用資源少些。舊社會地主就是這麼對待長工的:幹活要快點,吃得要少點。程式員可以通過最佳化資料結構、演算法和代碼來提高軟體的效能。演算法複雜度分析是很好的方法,可以達到“未蔔Crowdsourced Security Testing”的功效。效能最佳化的目標是“既要馬兒跑得快,又要馬兒吃得少”,關鍵任務是找出限制效能的“瓶頸”,不要在無關痛癢的地方瞎忙活。例如,在大學裡當教師,光靠賣力氣地講課或者埋頭做實驗,職稱是升不快的。有些人找到了突破口,一年之內“造”幾十篇文章,爭取破格升副教授、教授。在學術上走捷徑,這類“學者”的品質真讓人擔憂。效能最佳化就好像從海綿裡擠水一樣,你不擠,水就不出來,你越擠海綿越幹。有些程式員認為現在的電腦不僅速度越來越快,而且記憶體越來越大,因此軟體效能最佳化的必要性下降了。這種看法是不對的,殊不知隨著機器的升級,軟體系統也越來越龐大和複雜了,效能最佳化仍然大有必要。最具有代表性的是三維遊戲軟體,如《Delta Force》、《古墓麗影》、《反恐精英》等,如果不對軟體(關鍵是遊戲引擎)做精益求精的最佳化,要想在一台普通的PC上順暢地玩遊戲是不太可能的。
易用性易用性是指使用者使用軟體的容易程度。現代人的生活節奏快,幹什麼事都可能想圖個方便,所以把易用性作為重要的品質屬性無可非議。導致軟體易用性差的根本原因是開發人員犯了“錯位”的毛病:他以為只要自己用起來方便,使用者也一定會滿意。俗話說“王婆賣瓜,自賣自誇”。當開發人員向使用者展示軟體時,常會得意地講:“這個軟體非常好用,我操作給你看,……是很好用吧!”軟體的易用性要讓使用者來評價。如果使用者覺得軟體很難用,開發人員不要有逆反心理:哪裡找來的笨蛋!其實不是使用者笨,是自己開發的軟體太笨了。當使用者真的感到軟體很好用時,一股溫暖的感覺就會油然而生,於是就會用“介面友好”、“方便易用”等詞來誇獎軟體的易用性。
清晰清晰意味著工作成果易讀、易理解,這個品質屬性工作表達了人們的一種質樸的願望:讓我花錢買它或者用它,總得讓我看明白它是什麼東西。我小時候的一個夥伴在讀中學時就因搞不明白電荷為什麼還要分“正”和“負”,覺得很煩惱,便早早地輟學當了工人。開發人員只有在自己思路清晰的時候才可能寫出讓別人易讀、易理解的程式和文檔。可理解的東西通常是簡潔的。一個原始問題可能很複雜,但高水平的人就能夠把軟體系統設計得很簡潔。如果軟體系統臃腫不堪,它遲早會出問題。所以簡潔是人們對工作“精益求精”的結果,而不是潦草應付的結果。在生活中,與簡潔對立的是“囉唆”。廢話大師有句名言:“如果我令你過於輕鬆地明白了,那你一定是誤解了我的意思。”中國小說中最“婆婆媽媽”的男人是唐僧。有一項民意調查:如果世上只有唐僧、孫悟空、豬八戒和沙僧這四類男人,你要嫁給哪一類?請列出優先順序。調查結果表明,現代女性毫不例外地把唐僧擺在最後。
很多人在讀研究生時有一種奇怪的體會:如果把文章寫得很簡潔,讓人很容易理解,投稿往往中不了,只有加上一些玄乎的東西,把本來簡單的東西弄成複雜的,才會增加投稿的命中率。雖然靠這種做法可能有效,可千萬不要把此“經驗”應用到產品的開發中!
安全性這裡的安全性是指資訊安全,英文是Security而不是Safety。安全性是指防止系統被非法入侵的能力,既屬於技術問題又屬於管理問題。資訊安全是一門比較深奧的學問,其發展是建立在正義與邪惡的鬥爭之上的。這世界似乎不存在絕對安全的系統,連美國軍方的系統都頻頻遭駭客入侵。如今全球駭客泛濫,真是“道高一尺,魔高一丈”啊!對於大多數軟體產品而言,杜絕非法入侵既不可能也沒有必要。因為開發商和客戶願意為提高安全性而投入的資金是有限的,他們要考慮值不值得。究竟什麼樣的安全性是令人滿意的呢?一般地,如果駭客為非法入侵花費的代價(考慮時間、費用、風險等多種因素)高於得到的好處,那麼這樣的系統就可以認為是安全的。
可擴充性可擴充性反映了軟體適應“變化”的能力。在軟體開發過程中,“變化”是司空見慣的事情,如需求、設計的變化,演算法的改進、程式的變化等。由於軟體是“軟”的,是否它天生就容易修改以適應“變化”?關鍵要看軟體的規模和複雜性。如果軟體規模很小,問題很簡單,那麼修改起來的確比較容易,這時就無所謂“可擴充性”了。要是軟體的代碼只有100行,那麼“軟體工程”也就用不著了。如果軟體規模很大,問題很複雜,倘若軟體的可擴充性不好,那麼該軟體就像用卡片造成的房子,抽出或者塞進去一張卡片都有可能使房子倒塌。可擴充性是系統設計階段重點考慮的品質屬性。
相容性相容性是指兩個或兩個以上的軟體相互交換資訊的能力。由於軟體不是在“真空”裡應用的,它需要具備與其他軟體互動的能力。例如,兩個文書處理軟體的檔案格式相容,那麼它們都可以操作對方的檔案,這種能力對使用者很有好處。國內金山公司開發的文書處理軟體WPS就可以操作Word檔案。相容性的商業規則是:弱者設法與強者相容,否則無容身之地;強者應當避免被相容,否則市場將被瓜分。如果你經常看香港拍的“黑幫”影片,你就很容易明白這個道理。所以WPS一定要與Word相容,否則活不下去。但是Word絕對不會與WPS相容,除非WPS在中國稱老大。
可移植性軟體的可移植性指的是軟體不經修改或稍加修改就可以運行於不同軟硬體環境(CPU、OS和編譯器)的能力,主要體現為代碼的可移植性。程式設計語言越低級,用它編寫的程式越難移植,反之則越容易。這是因為,不同的硬體體繫結構(如Intel CPU和SPARC CPU)使用不同的指令集和字長,而OS和編譯器可以屏蔽這種差異,所以進階語言的可移植性更好。C++/C是一種中級語言,因為它具有靈活的“位操作”能力(因此具有硬體操作能力),而且可以直接嵌入彙編代碼。但是C++/C並不依賴於特定的硬體,因此比組合語言可移植性好。Java是一種進階語言,Java程式號稱“一次編譯,到處運行”,具有100%的可移植性。為了提高Java程式的效能,最新的Java標準允許人們使用一些與平台相關的最佳化技術,這樣最佳化後的Java程式雖然不能“一次編譯,到處運行”,仍然能夠 “一次編程,到處編譯”。一般地,軟體設計時應該將“裝置相關程式”與“裝置無關程式”分開,將“功能模組”與“使用者介面”分開,這樣可以提高可移植性。 本文節選自《高品質程式設計指南:C++/C語言》
林銳,韓永泉編著
電子工業出版社出版