題記:
《.NET中的設計模式》系列隨筆停下有一段時間了,一則總結個東西不容易,另一則,不想寫相同的內容(如果朋友們沒有在我的隨筆中看到新東西,我認為是浪費大家的時間,也是一種失敗)。
今天開題之前先讓大家見一個老朋友,相信沒有一個人會不認識它:-)大家是不是覺得很眼熟啊。程式中產生一個錯誤的原因很簡單,解決方案也很簡單,我也相信寫過兩年代碼的人只要稍微細心一點就很少遇到這個問題。拋去原因,相信很多人是這麼解決此類問題的:
if(obj!=null){}
然而一個項目中,各種類似變數成千上萬,如果每個地方都這麼判斷,不僅浪費體力,而且讓代碼醜陋,甚至因為遺漏而出現低級Bug。相信這都不是大家願意看到的。那麼有沒有好的解決辦法呢?答案就是空模式!
空模式不屬於《GoF23種設計模式》,最早接觸它,是在一本Java中的設計模式書中,用Java的人應該都知道(如果用Java幾年還不知道就無語了...)。然而既然是設計模式,.NET中一樣可以用(工具無優劣,挫人論高低)。
空模式,其目的是為了保證代碼的安全和優雅,避免醜陋的代碼。
還回到已開始的錯誤情境,其實我們最希望的解決方式不是解決Bug,而是Bug不存在,那麼空模式怎麼解決此類問題呢?先看下面的範例程式碼:
//為業務對象定義一個不做任何事情的基類, public class BusinessBase { //為該類型定義一個Empty靜態成員 public static BusinessBase Empty = new BusinessBase(); public virtual void DoSomething() { Console.WriteLine("This is a null object,it can't do anything."); } } //在擴充類型做具體的事情 public class BusinessA : BusinessBase { public override void DoSomething() { Console.WriteLine("Niyw is doing something."); } }
通常我們的代碼會這麼寫
static void TestNormal() { Console.WriteLine("測試傳統方法."); BusinessBase bb = GetBusinessNormal(true); if(bb!=null) bb.DoSomething(); else Console.WriteLine("出錯啦."); bb = GetBusinessNormal(false); if (bb != null) bb.DoSomething(); else Console.WriteLine("出錯啦."); } static BusinessBase GetBusinessNormal(bool flag) { try { if (flag) return new BusinessA(); throw new Exception("出錯啦."); } catch { return null; } }
使用空模式時,代碼如下:
static void TestEmptyPattern() { Console.WriteLine("測試空模式."); BusinessBase bb = GetBusinessEmptyPattern(false); bb.DoSomething(); bb = GetBusinessEmptyPattern(true); bb.DoSomething(); } static BusinessBase GetBusinessEmptyPattern(bool flag) { try { if(flag) return new BusinessA(); throw new Exception("出錯啦."); } catch { return BusinessA.Empty; } }
通過比較上面的兩段代碼,一般情況下四行的業務代碼,為了容錯,至少要寫6行的容錯代碼,而使用空模式時,不用增加任何一行容錯代碼。是不是發現用了空模式後代碼更加優雅簡單,並且安全性提高了很多.
小結:空模式是一種很簡單的模式,甚至不算是模式。然而它代表了一種很好的編碼習慣,在具體項目開發過程中,如果用好類似的習慣,相信開發效率會更高,個人技能也會更高。