はじめに
今回はNullReferenceException
のスローを防ぐためのnullチェックを減らすことができるNull Object パターン
について紹介したいと思います。
よくあるnullチェック
class Client { // UserObject のインスタンスを管理しているもの static IRespository _respository = new Repository(); private static void Main(string[] args) { // userObjectを取得する var obj = _respository.GetUserObject(); // nullチェックをしないといけない if (obj != null) { obj.Execute(); } } } public class UserObject { public void Execute() { Console.WriteLine("Execute."); } }
Null Objectパターン適応後
Null Object
パターンは、何もしないNullObject
をnull
の代わりに用いることで解決します。
class Client { // Abstractionのインスタンスを管理しているもの static IRespository _respository = new Repository(); private static void Main(string[] args) { // IAbstractionを取得する var abstraction = _respository.GetAbstraction(); // GetAbstractionメソッドの返り値はnullにならない(しないようにする)ためnullチェックが必要ない abstraction.Execute(); } } public interface IAbstraction { void Execute(); } public class RealObject : IAbstraction { public void Execute() { Console.WriteLine("Execut."); } } public class NullObject : IAbstraction { public void Execute() { // 何も処理しない } }
さいごに
クライアントを実装する人がNull Objectパターン
を用いて実装されていることを知らされていなかった場合に結局意味がなくなってしまうのではないかとも思います。
C#
は型が厳格なところが魅力ですし,おそらくインターフェイスは参照型であるという知識から自然とnullチェックを行ってしまうのではないでしょうか。
まあちゃんと情報共有やコメントを残しておけと言われればそうですが、シグネチャだけでは難がありそうです。
またクラスの数が増えてしまうデメリットもありますが、クライアントの簡素化・テストの容易化できるメリットもあるので,このパターンはそこらへんのトレードオフを考えてみると良いと思います。
ではまた。