|
ニュース検索
ピックアップ
今週のIT求人情報
|
C#におけるNull ObjectパターンはじめにNullオブジェクトとは、オブジェクトが存在しないことを表すオブジェクトです。何の動作も行わずに、デフォルトを返します。Nullオブジェクトは、オブジェクト参照がNullである場合に使われます。Null Objectパターンはクライアントコードを簡素化し、誤りを生じにくくするのに役立ちます。例えば、顧客アカウントを確認し、顧客がゴールド会員であるかどうかをチェックする簡単な販売アプリケーションを考えてみましょう。ゴールド会員は、割引や配送料無料など、さまざまな特典を受けることができるものとします。 以下は、 mainメソッドのコードスニペットです。顧客のアカウント情報を取得し、そのゴールド会員プロファイルを取り出し、そのゴールド会員に適用されるすべての特典を適用します。
string userName = args[0];
string pin = args[1];
Order order = new Order();
for (int i = 2; i < args.Length; i++)
{
order.Amount += Convert.ToDecimal(args[i]);
}
var account = AccountController.GetAccount(userName, pin);
if (account == null)
{
Console.WriteLine("Invalid Account");
}
else
{
var gProfile = GoldMembershipController.GetProfile(account);
if (gProfile != null)
{
order.Amount -= gProfile.GetDiscount(order.Amount);
}
if (gProfile != null)
{
if (!gProfile.IsShippingFree)
{
order.Amount += order.GetShippingCharges();
}
}
else
{
order.Amount += order.GetShippingCharges();
}
Console.WriteLine(string.Format("Total Amount: {0}", order.Amount));
}
AccountController.GetAccount(userName, pin)はAccountオブジェクトを返し、それ以外の場合はnullを返します。同様に、顧客がゴールド会員であれば、GoldMembershipController.GetProfile(account)はGoldMembershipオブジェクトを返し、ゴールド会員でない場合はnullを返します。上のコードスニペットから分かるように、null参照をチェックする条件文が何度も繰り返し出現します。条件文は通常、条件結果に基づいて分岐するために使用します。上のゴールド会員であるかをチェックする部分では、同じフローの中で、null参照をチェックするためだけに2つの条件文が使用されています。これでは、コードが長くなって理解しにくくなるだけでなく、大きなプログラムではnullのチェックを忘れてしまいがちであるため、非常に誤りが生じやすくなります。Null Objectパターンは、このような問題を解決するためのものです。 Null Objectパターンを実装すると、 GoldMembershipController.GetProfile(accountId)は常にオブジェクトを返すことになります。顧客がゴールド会員ではない場合には、Nullオブジェクトを返します。Null Objectパターンを実装するには、IGoldMembershipインターフェースを作成し、GoldMembershipクラスとNullGoldMembershipクラスの両方でこのインターフェースを実装します。NullGoldMembershipクラスは、何も行わずにデフォルトを返すだけのクラスです。GoldMembershipController.GetProfile(accountId)メソッドも変更し、ユーザーがゴールド会員である場合はGoldMembershipオブジェクト、ゴールド会員でない場合はNullGoldMembershipオブジェクトを返すようにします。
public interface IGoldMembership
{
decimal GetDiscount(decimal amount);
bool IsShippingFree { get; set; }
}
public class GoldMembership : IGoldMembership
{
public GoldMembership(string userName)
{
// get gold member profile of this user
IsShippingFree = true;
}
public bool IsShippingFree { get; set; }
public decimal GetDiscount(decimal amount)
{
decimal discount = 100;
//calculate discount
return discount;
}
}
public class NullGoldMembership : IGoldMembership
{
public NullGoldMembership()
{
IsShippingFree = false;
}
public decimal GetDiscount(decimal amount)
{
return 0;
}
public bool IsShippingFree { get; set; }
}
public class GoldMembershipController
{
public static IGoldMembership GetProfile(Account account)
{
// if this account has gold membership
// return profile else return null
if (account.Type == "GoldMember")
{
return new GoldMembership(account.UserName);
}
else
{
return new NullGoldMembership();
}
}
}
mainメソッドのコードは、次のようになります。
string userName = args[0];
string pin = args[1];
Order order = new Order();
for (int i = 2; i < args.Length; i++)
{
order.Amount += Convert.ToDecimal(args[i]);
}
var account = AccountController.GetAccount(userName, pin);
if (account == null)
{
Console.WriteLine("Invalid Account");
}
else
{
var gProfile = GoldMembershipController.GetProfile(account);
order.Amount -= gProfile.GetDiscount(order.Amount);
if (!gProfile.IsShippingFree)
{
order.Amount += order.GetShippingCharges();
}
Console.WriteLine(string.Format("Total Amount: {0}", order.Amount));
}
しかし、Null Objectパターンを使用すればnull参照を完全になくすことができるわけではありません。オブジェクトが存在するか否かによって分岐しなければならない場合もあり、そのような場合にはやはりnull参照を使用する必要があります。例えば、ユーザーが有効なアカウントを所有しない場合は、その後の処理は行わず、単にエラーメッセージを表示します。このような場合には、次のようにnull参照を使用し、チェックする必要があります。
var account = AccountController.GetAccount(userName, pin);
if (account == null)
{
Console.WriteLine("Invalid Account");
}
else
{
// process the transaction
}
著者紹介Sajad Deyargaroo(Sajad Deyargaroo)
MCTS、MCP資格を取得。VB 4.0とC++のアプリケーション開発からこの世界に入る。プログラミングへの関心は数多くの言語にわたるが、現在は.Netに没頭している。最近は、AISとともにMicrosoftの技術に取り組んでおり、複数の雑誌およびWeb上に多くの記事を執筆している。電子メールアドレスはsajad@programmer.net。
関連記事 関連テーマ
新着ニュース・コラム ホワイトペーパー
|
注目のトピックス 話題の記事
企業の約4割がいまでも IE 6 以前のブラウザを利用 ― Web 広告研究会調査
SNS「非モテ+」、バレンタイン関連ワード投稿を禁止に
Android アプリを美しくみせる UI デザイン10のヒント
イギリス人は年間11キロのチョコを食べている―トリップアドバイザー「世界のチョコレート消費量」を公開
Android 版 Chrome ベータ1登場、ただし Android 4.0に限る
⇒一覧を見る
アクセスランキング
最新コラム一覧
|
||||||||||||||||||||