目的/使用時機
-
在 method 中可能回傳 null,並在使用時加上是否為 null 的判斷,想改善這種寫法。
-
實做的內容為 do nothing。
說明
簡單來講就是產生一個 object,取代單純回傳 null,其內容不做任何事情(或是做一些 default 的行為),讓 client 端呼叫時不會發生錯誤。
範例
建立一個 interface 或 abstract class
interface ICar
{
void Run();
}
接著定幾個class繼承上述的介面:
class FastCar : ICar
{
public void Run()
{
Console.WriteLine("Run fast");
}
}
class SlowCar : ICar
{
public void Run()
{
Console.WriteLine("Run slow");
}
}
寫個 factory 用來產生實體:
ICar CarFactory(int i)
{
if (i == 0)
return new FastCar();
else if (i == 1)
return new SlowCar();
else
return null;
}
client端程式:
ICar MyCar = CarFactory(0);
MyCar.Run(); // Run fast
MyCar = CarFactory(1);
MyCar.Run(); // Run slow
MyCar = CarFactory(2);
MyCar.Run();
執行到最後一個 MyCar.Run() 時,發生Exception:System.NullReferenceException
原因為最後一次的 CarFactory 並沒有產生實體,所以在呼叫 Run() 時會出現 exception,那要怎麼解決呢?這時候就可以使用 Null Object Pattern。
建立一個null class
一樣繼承 ICar interface, Run() 裡面不做任何事。
class NullCar: ICar
{
public void Run()
{
// Do nothing
}
}
更改原來的factory
將原來的 return null 改寫成return new NullCar()
新的 factory 變成:
ICar CarFactory(int i)
{
if (i == 0)
return new FastCar();
else if (i == 1)
return new SlowCar();
else
return new NullCar();
}
相同的client端程式再呼叫一次則可正常運作,不會有任何錯誤出現。
優點
-
減少程式碼中的判斷和條件分支,使程式碼更加簡潔。
-
增加程式的可靠性和可擴展性,因 null 物件較易產生錯誤或例外,而 Null Object 會實作相同的介面或類別,為使用者提供一個預期的、可預測的行為。
缺點
- 增加程式的複雜度,因為必須實作一個特殊的 Null Object,並且在程式中使用它。