[問題] Private method 該不該確認參數正確性?
如題
public methods 應該不需要討論了
假設是一個多人合作的專案
你開發的部分很可能之後會換人維護
那麼有必要在 private method 進行參數的 validation 嗎?
我稍微找了一下, 網路上的答案大概有兩類:
1. Using assertion to check in private method
2. Using auto test to insure that the function is not violating your assumptions
大家都認為不該花運算時間在裡面
但人有失蹄馬有亂手
也有可能之後的維護者直接新增 public 介面呼叫 private method
如果是上述的情況似乎 (1), (2) 都無法避免產生問題
不過每個 private method 都檢查參數似乎也有點瘋狂
不知道大家都如何處理此類問題呢?
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 59.120.41.39
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1422176579.A.1A9.html
→
01/25 17:04, , 1F
01/25 17:04, 1F
推
01/25 17:20, , 2F
01/25 17:20, 2F
這邊是泛指應該讓程式維持正常的檢查, 就算是 integer 有時也需要檢查~
推
01/25 18:10, , 3F
01/25 18:10, 3F
→
01/25 18:10, , 4F
01/25 18:10, 4F
推
01/25 19:23, , 5F
01/25 19:23, 5F
我也覺得責任應該在實作 public member func 的人
assertion 就是為了希望在開發期就可以發現
→
01/25 22:47, , 6F
01/25 22:47, 6F
→
01/25 22:48, , 7F
01/25 22:48, 7F
Compiler 可以最佳化到這種程度嗎 XD
另外您的有問題是指? 效率有問題 profiling 再去處理嗎?
→
01/26 20:46, , 8F
01/26 20:46, 8F
推
01/27 08:39, , 9F
01/27 08:39, 9F
哈哈被其它語言荼毒用習慣 method 了 xD
→
01/27 08:39, , 10F
01/27 08:39, 10F
→
01/27 08:40, , 11F
01/27 08:40, 11F
→
01/27 08:40, , 12F
01/27 08:40, 12F
→
01/27 08:41, , 13F
01/27 08:41, 13F
→
01/27 08:41, , 14F
01/27 08:41, 14F
→
01/27 08:42, , 15F
01/27 08:42, 15F
→
01/27 08:42, , 16F
01/27 08:42, 16F
→
01/27 08:42, , 17F
01/27 08:42, 17F
這幾天我仔細了想了一想, 加上諸位先進的想法, 我整理一下目前我的觀點:
1. 為什麼我們要做參數檢查?
為了防止程式產生預期之外的行為
2. 為什麼我們不在 private function 做參數檢查?
因為 private function 的參數是我們能掌握的, 如同殺手貓說的一樣,
有外部防火牆擋住, 所以 pass 給 private function 的參數應該都是正確的
3. 那麼在 private function 做參數檢查有什麼壞處呢?
既然參數是正確的, 多做檢查只是浪費計算資源, 而且會多寫不必要的程式碼
4. Compiler 有可能幫我們最佳化 private function 的參數檢查嗎?
這部分我試寫了一個簡單的小程式:
class A {
public:
float Sqrt(float a)
if (a < 0) return 0;
else return _Sqrt(a)
private:
float _Sqrt(a)
if (a < 0) return 0;
else return sqrt(a)
}
int main() {
A a;
cin >> b;
cout << a.Sqrt(b);
}
在 g++ 4.6.3 -O 沒開的時候的確會檢查兩次, 而 -O 時則只會檢查一次
因此, 也許很多情況, 在 private fucntion 做參數檢查並不會影響太多的效
能
假想一下, 現在有一群人在開發假設, 同一個 class (不一定誰先誰後, 或同時)
我們規定了傳遞給 private function 的人一定要給予正確的參數, 那麼情況會
變成:
A 製作了一個 private function _SetupDev, 用在 public function LoadDev
B 現在想要使用 _SetupDev:
bool _SetupDev(int SleepPeriod, int MaxJobs, int MinJobs);
那麼, B 該傳什麼參數給 _SetupDev?
我想通常的行為要不 B 跑去問 A, 要不 B 必須要去看 LoadDev 寫了什麼
bool LoadDev(string strFileName) {
...
if (1 > SleepPeriod || MinJobs < 0 || MaxJobs < MinJobs) {
ReportError;
}
...
所以 B 了解了 _SetupDev 的 SleepPeriod 不能小於 1...
而另一個方案, 我們規定, 所有 function 都應該檢查它自己的參數正確性,
情況就變成:
if (ENUM_OK != _SetupDev(SleepPeriod, MaxJobs, MinJobs)) {
ReportError;
}
or
try {
...
_SetupDev(SleepPeriod, MaxJobs, MinJobs);
} catch ...
B 可以完全的不需要知道 _SetupDev 內部詳細的實作, 也可以避免因粗心造
成的參數誤傳; 另一方面, 我想檢查自己的參數正不正確, 感覺比確認給別
人的參數正不正確來得單純
寫到這邊, 我覺得之所以會有這種想法, 也許是因為以我們這種有可能多人
撰寫同一個 class 或維護的情況, 儘管是 private function, 對合作開發
的人來說也可以當作是一層 interface 了吧
但公司的職員往往來來去去, 也許這種狀況也無法避免就是
→
01/27 18:30, , 18F
01/27 18:30, 18F
→
01/27 18:31, , 19F
01/27 18:31, 19F
→
01/27 18:33, , 20F
01/27 18:33, 20F
→
01/27 18:37, , 21F
01/27 18:37, 21F
→
01/27 18:38, , 22F
01/27 18:38, 22F
→
01/27 18:38, , 23F
01/27 18:38, 23F
→
01/27 18:45, , 24F
01/27 18:45, 24F
→
01/27 18:45, , 25F
01/27 18:45, 25F
的確, caller 忘記檢查也是意外的錯誤, 但或許這個意外錯誤呈現的方式可能會不同?
也許是 Error code v.s. SIGSEGV? XD
※ 編輯: Ebergies (59.120.41.39), 01/27/2015 20:30:27
討論串 (同標題文章)
完整討論串 (本文為第 1 之 2 篇):