2013年11月10日 星期日

Round 9: Exceptions - involve the users

當使用者有可能因操作引發例外時,程式處理例外的方式應為:適度提示使用者,讓他有機會更正此項錯誤,並繼續正常執行

U步驟:

檢視innerProduct程式,可發現可能引發innerProduct計算的dimension error。同此,檢視linearTransform程式,亦可發現同樣的問題。

SP8:處理innerProduct與linearTransform的dimension error。

D步驟:

T37:寫innerProduct測試innerProduct dimension檢查,及拋出例外;決定如何處理innerProduct dimension例外,做必要的程式修改。


T38:寫linearTransform測試、linearTransform dimension檢查,及拋出例外;決定如何處理linearTransform dimension例外,做必要的程式修改。

C步驟:

T37:寫innerProduct測試innerProduct dimension檢查,及拋出例外;決定如何處理innerProduct dimension例外,做必要的程式修改。

利用overload特性,先不修改既有的innerProduct,寫測試如下:

TEST (dimension_exception, innerProduct){
double a[2]={0,1};
double c[3]={1,2,3};
vector u(2,a);
vector w(3,c);

try {
innerProduct(u,w);
}
catch (string s){
CHECK(string("innerProduct: dimension error!") == s);
}

}

innerProduct函數如下:

double innerProduct(const vector &u, const vector &v){
if (u.dim() != v.dim()){
throw std::string("innerProduct: dimension error!");
}
double p=0;
for (int i=1; i <= u.dim(); ++i)
p = p+u[i]*v[i];
return p;
}

事關使用者,故在main中處理,

try {
cout << "inner product is " << innerProduct(u,v)<< endl;
}
catch (string s){
cout << s << endl;
}

我寫的程式請你參考。T38請你試試看。

L步驟:比較原有innerProdct

  bool innerProduct(double & p,const vector &u, const vector &v)

可見新的innerProduct介面

  double innerProduct(const vector &u, const vector &v)

較為直覺、簡約;此一特性充分顯示在innerProduct的使用上。

原innerProduct

1. 內積計算牽涉兩個向量,但innerProduct有三個參數,閱讀程式者須花一些額外的功夫判斷才知道第一個參數的為輸出參數
2. 呼叫原先innerProduct處,需要檢查還傳值為true或false,強迫programmer在每一個呼叫innerProduct處作錯誤處理,使正常處理與錯誤處理的code混合在一起,不易閱讀。

相對的,新innerProduct

1. 內積計算牽涉兩個向量,innerProduct有二個輸入參數,傳回值為double,閱讀程式者較容易理解。
2. 新的innerProduct可直接呼叫。惟當dimension例外需要被處理時,programmer才使用try statement。如果dimension例外應被視為bug而須採用fail fast處理方式終止程式,則程式碼將能維持乾淨、簡單。

這些優點來自於C++ 例外處理機制,它讓例外狀況自有管道,不需借用function的介面回傳,並讓programmer有具體的方法分離正常處理與例外處理的code。

繼續回顧的工作。程式還有哪些可以改善的地方?

首先,以使用者觀點回顧,SP2尚未解決,使用者可能輸入格式不正確的向量、矩陣。現在,你處理的手段變多了,例如使用例外,且因該問題面向使用者(user facing),所以你需要讓程式繼續執行,並讓使用者有修正的機會。處理這個問題的方法之一是以字串方式取得使用者輸入,再加以解析(parse)以偵測是否格式錯誤;請你試試看。

其次,以programmer觀點回顧,你可以試著review現有的code,發現值得改善之處。例如,尋找重複的code (duplicated code),以函數取代之;請你也試試看。



© Y C Cheng, 2013. All rights reserved.

沒有留言:

張貼留言