Showing posts with label exception. Show all posts
Showing posts with label exception. Show all posts

Friday, September 07, 2001

Re: 請問在何種狀況下會考慮使用exception?

  就大部分的軟體系統而言,想在程式還沒完成時就知道效率的瓶頸在哪?無異是緣木求魚!

  在應該使用 Exception 時就使用,在程式還沒正確之前,效率再高都是枉然。

  在設計之初,最重要的是程式的高階效率,所謂高階效率,就是要求撰寫易於找出錯誤、易於日後陸續修改、具備高度重複使用性的程式碼。

  程式的架構要清爽、明確且具彈性。才可在未來應付以上這些變局。

  以設計一個函式庫為例,函式庫的設計者知道如何偵測例外,卻無法預知函式庫的使用者要如何處理這個例外,這時就是 Exception 使用的時機了。

  換言之,當你設計的軟體系統可以區分為設計者及使用者時,也就是你在設計給未知使用者使用的軟體時,你就可以在偵測到例外時,將之丟出。而且盡量不要使用傳統上應付這種情形的其他任何方法,如:傳回錯誤代碼等。

  在 C++ 中,你還可以利用 assert 敘述,在這裡建議 assert 敘述使用於內部供軟體設計者偵錯用;而 exception 用於公開的介面部分,供軟體元件使用者例外處理用。──當然啦!這也不是絕對的標準,端看您對自己設計的元件作何假設而定。


※ 引述《AskaLee2 (Aska)》之銘言:

請問各位先進,在何種狀況下使用exception機制最適當??
使用exception必須付出一些效能上與空間上的代價,
應該有某些狀況非常適合使用exception。
Tags: [] [] [] []

Thursday, June 28, 2001

Assertion

Assertion 的使用目的,就是要防止客戶對程式庫的誤用。以 Design by Contract 的原則再加上 OOP 的術語,簡單說來:就是要確保物件在執行操作或行為後還要維持其內部狀態的正確。

假設描述物件這個行為的程式本身正確無誤,而作業系統也沒來找碴,那使物件狀態脫軌的必定來自物件使用者傳入錯誤的引數。

就如同程式行為發生“例外”一樣,程式庫的使用者知道如何偵測錯誤的物件狀態,但卻不知如何處理...

傳統 C 語言的 assert 做法,就是一偵測到要確認的條件不成立了,就立刻終止整個程式的執行,並列印一些偵錯訊息出來。

但是,在這個愈來愈趨向動態的程式世界。有時連客戶都無法確保傳入的引數是正確的,原因可能不是客戶不夠小心,而是在動態的世界裡,這是無法避免的。

這時,在 C++ 中可行的個解法,就是丟出“例外”。被丟出的例外可以被客戶捕捉,並作一些處理措施。萬一客戶不處理,才將程式終結掉。

我這裡使用的,就是裹著 Assertion 的例外,並利用 template 來讓客戶決定要丟出的例外種類:

From: "Jiang Yu-Kwan"
Sent: Monday, June 18, 2001 4:40 PM
Subject: Re: Fw: JavaOne特別報導

我再看了一下,它支援的是 generic programming,而 template 只是在C++下的實作方式。

以 JAVA 設計的哲學,它可能把GP搞得跟 C++ 的 template 語法很像,但骨子裡卻不必preprocessor處理,而是直接在 run time support。

而 assertion 的支援,只是為了支援 Design by Contract ,其支援的完整性,可能更勝 C。

因為 C++ 對 assertion 沒有更進一步的支援(直接沿用C的做法)。所以, JAVA 在這點有很大的改進空間。

以下我就舉例說明一下,如何製造一個 C++ 版本的 assertion 功能:

 1: // assertion.h
 2: //...
 3: 
 4: template <class Exception> void Assert( bool assertion )

 5: {
 6:     if (! assertion) throw Exception();

 7: }
 8: //...
 9: 

經修改後,我現在實際使用的 assertion 版本如下:

1: // Assertion for C++ version.
2: template <class Exception> inline void Assert( bool assertion )

3: {
4: #ifndef NO_CPP_ASSERTION
5:     if (! assertion) throw Exception();

6: #endif
7: }
 1: // user.c
 2: #include "assertion.h"
 3: //...
 4: class Date {

 5: public:
 6:     class Bad_arg{};
 7:     setMonth( int mon );

 8:     //...
 9: private:
10:     //...
11: };
12: 

13: void Date::setMonth( int mon )
14: {

15:     // 確保設定的月數在正確的範圍,否則,
16:     // 就丟出Bad_arg的例外。
17:     Assert<Bad_arg>(1<=mon && mon<=12);

18:     //...
19: }
20: //...
21: 

更進一步的探討可以參考 C++ 之父, Bjarne Stroustrup 所著的 《The C++ Programming Language 3rd Edition》。