程式設計中最常使用的邏輯控制就是 if 跟 case 了。
什麼時候該用 if ?什麼時候用 case 呢?
我會使用 case 的情況,通常是條件是單純的,如:依據判斷變數的值,進行不同的處理方式。
邏輯的控制寫得好不好,關係到您的程式執行的效率與正確性,以下我們就分 if 跟 case 兩個部分來說明,撰寫程式時該注意的地方。
if statement
.先寫正常流程部分,再寫例外的狀況
.不要將正常的狀況擺在 else 的部份
先把正確的情況處理好,再來處理例外的狀況,這是 common sense,不過是否一定就是要將正確的狀況擺在前面,書中雖然這樣建議,但我覺得還是要看情況,有時候例外的情況很常發生的時候,將例外狀況寫在前面反而會讓程式比較早離開判斷區塊。
OpenFile(InputFile, Status)
if Status=Error then
ErrorType=FileOpenError
else
ReadFile(InputFile, FileData, Status)
if Status=Success then
SummarizeFileData(FileData,SummaryData,Status)
if Status=Error then
ErrorType=DataSummaryError
else
ErrorType=None
end if
else
ErrorType=FileReadError
end if
end if
改成如下:
OpenFile(InputFile,Status)
if Status<Error then
ReadFile(InputFile,FileData,Status)
if Status=Success then
SummarizeFileData(FileData,SumaryData,Status)
if Status<>Error then
ErrorType=None
else
ErrorType=DataSummaryError
end if
else
Error=FileReadError
end if
else
Error=FileOpenError
end if
這樣閱讀起來以及做錯誤追蹤的時候,就會容易許多
.if 部分要具有意義
避免掉空的 if 敘述,其實有時候是因為邏輯想破頭的關係,才會發生這種狀況,與其留一個空的敘述,不如就直接寫反向的部份即可
if SomeTest then
'do nothing
else
' do something
...
end if
改成
if not SomeTest then
' do something
...
end if
.利用布林函數來取代複雜的程式碼
如果邏輯判斷的條件很複雜的時候,最好將這些判斷條件寫成布林函數來呼叫,這樣的好處是,如果同樣的條件判斷需要經常使用時,寫成布林函數可以節省掉很多程式撰寫的時間。
.審慎考慮 else 的部份
.將最常發生的情況寫在前面
.確定所有的狀況都已掌握
有時候可能會覺得,放個 else 多此一舉,不過如果把它當作 debug 的一部分,確實是有幫助的,所以寫程式的時候不妨多想一想,放個 else 區塊吧!
case statement
.依字母順序來排列
如果說 case 的順序對於程式的運作沒有影響的話,那麼依照字母或數字大小順序來排列,是一種方便閱讀的方式。
.正常狀況放在最前面
.依發生頻率擺放
這兩個部分對於程式的效率都相當有用,當符合條件的狀況愈早發生,就會愈早離開條件判斷的區塊,程式執行起來比較有效率。
.保持簡潔的 case 執行動作
case 結構愈清楚,對於程式的閱讀很有幫助。如果在 case 的區塊中寫了很複雜的程式段,反而會讓 case 區塊變得不容易閱讀,這時候將複雜的程式段改以常式取代,用呼叫常式的方式來取代冗長的程式
select case x
case 'A'
doA()
case 'B'
doB()
case 'C'
doC()
else
doElse()
end select
.不要為了用 case 而用 case
因為 case 比 if-else 好寫,那我就儘可能將條件判斷改成 case 就好了?
例如:
select case left(x,1)
case 'A'
if x="ABC" then
else if x="ACD" then
end if
end select
如果是這種情況,倒不如就直接使用 if 敘述吧!
.使用 default 部分來處理錯誤
善用 defalut 的區塊,對於錯誤的偵測相當有幫助的,當一時之間無法考慮到所有狀況時,透過 default case 的處理,可以讓我們發現一些沒有考慮到的因素。
以前學C時常犯的錯誤:忘了寫break
然後程式一跑就fall through
都怪C真笨,不會自己判斷...
(其實是自己沒學好..XD)
嗯 C like 的語言 switch 中間都會有一大堆 break
真是讓人 take a break...XD
.Net 的 C# 不知道有沒有改善這一點?
果然C#保留了一致以來的「特色」^_^
C# 也有break.
如果case裡沒有break.
他會繼續處理接下來(下個case)的邏輯,直到遇到break為止.
如果有一些商業邏輯是需要靠像switch case這樣來依照case來處理,然後又會頻繁變動的話,可以把case跟需要執行的動作用Command Pattern來實作,這樣就比較不會動到主程式。