2011-08-30 9 views
4

nullオブジェクトパターンを使用して、場所全体でヌルチェックが多い大きなクラスをリファクタリングしています。これまでのところ、ほぼ円滑な変更が行われていましたが、私は最終結果にいくつかの問題を抱えています。より良い方法や違う方法があるのか​​、それとも元に戻すのかを知りたいと思います。Nullオブジェクトパターンにリファクタリングしようとしましたが、最終結果が悪化しているようです。

最大の問題は、私は次のコードを持っていることである。

IMyObject myObject = GetMyObject(); 
if(myObject != null && !myObject.BooleanProperty) 
    DoSomething(); 

あなたが見ることができるように、私はおそらく、この状態からヌルチェックを外すことができますが、私はデフォルト値に設定されている場合ブール型プロパティを持っていますコードを実行します。私がいつも真実を返すならば、私は発見して除去するのが辛い微妙なバグを導入するかもしれません。

もう一つの問題は、私はこのようなヌルからチェックを変更しなければならなかったということです。

if(myObject.GetType() != typeof(MyNullObject)) 
    return false; 

DoSomething(); 

だけではなく、ヌルをチェックする、今私は種類を確認する必要があるので、これは単なる醜いです。この種の状況は、オブジェクトのプロパティのいずれかを返さないか、メソッドの1つを実行していないため、このチェックを行う必要があるため、クラスで3回発生します。

最後に、オブジェクトにはnull可能ではないいくつかのDateTimeプロパティがあり、建築家はそれらをnullableにしたくありません。もう一度MinDateの値をデフォルトにすることで、いくつかの厄介なバグがコードにクロールする可能性があります。

あなたはそれを持っています。これは、ヌルオブジェクトパターンがスパゲッティのヌルチェックよりも悪い場合ですか?これを達成するより良い方法はありますか?

ご回答ありがとうございます。

+1

オブジェクトのnullをテストするために静的メソッドまたは拡張メソッドを定義する方法と、null以外の場合はプロパティを返しますか?おそらく、オブジェクトがnullの場合にfalseを返す場合はPropertyNameOrFalse、そうでない場合はTrueを返すと仮定するとPropertyNameOrTrueと命名できます。オブジェクトが存在する場合はプロパティの値を返し、そうでない場合はdefaultValueを返すPropertyNameOrDefault(defaultValue)を持つこともできます。 – supercat

答えて

0

ヌルオブジェクトパターンはトレードオフです。ヌルチェックを排除することで得られますが、維持する別のクラスでお支払いください。

IsNullブール値プロパティをインターフェイス/ベースクラスに追加することをお勧めします。

通常の実装では、falseが返されます。ヌルオブジェクトはtrueを返します。

これにより、正確なタイプに対するテストを避けることができ、あなたの意図がより明確になります。また、日付を扱うコードのテストとしてこれを使用して、null不可能な日付プロパティを保持することもできます。

+0

あなたはそうです、それはトレードオフであり、時には私たちが作ってくれるものではないかもしれません。このような場合、if(myObject == null)からif(myObject.IsNull)に変更されているように見えますが、それ以外の多くの利点(標準的な処理方法コード全体にわたる特別なケースとコードの重複の削減)私はおそらくそれをしません。 –

0

Code Contractsをご覧ください。これは、あなたが参照している問題の種類を避けるためのメソッドの前後の条件を強制するためのエレガントな方法です。これは、契約が実行時に破損した場合、または場合によっては静的分析(Microsoftフレームワーク)によって例外が発生する早期に発生させます。

私はCuttingEdge Condtionsを好んでいますが、静的解析はサポートしていませんが、流暢なインターフェイスがあり、Microsoft同等のものよりも直感的です。

それはあなたがこのようなコードを記述することができ、さらにはインターフェイスを拡張:

public class MyClass 
{ 
    public void MyMethod(string param1, int param2) 
    { 
     Condition.Requires(param1).IsNotNullOrWhiteSpace(); 
     Condition.Requires(param2).IsGreaterThan(0); 

     ... 
    } 
} 

あなたは、システムにすべてのデータ入力の条件を実装すなわち、すべてのパブリックメソッドと、これを違反したコードを作成する開発者を妨げます。バグのために起こると、例外とスタックトレースは、どこに問題があるかを正確に伝えます。

また、不変条件によって特定の条件が発生しないようにプロパティを監視する条件を設定する方法もあります。これは腐敗防止レイヤーとして機能し、バグを再度捕まえ、開発者がコードを書くことによってシステムが壊れることを防ぎます。

0

インターフェイスIMyObjectにboolean IsNull(IsEmpty)プロパティを追加し、そのプロパティに対してtrueを返すMyNullObjectを実装することがあります。明らかに、他の場合はfalseを返す必要があります。そうでなければ、間違った動作になります。

1

DoSomething()がヌルオブジェクトのメソッドであり、単純にノーオペレーションとして実装されるように、コードをリファクタリングする方がよいでしょうか?ヌルオブジェクトの別の代替方法はMaybe<T>です。これは、ヌルチェックをより読みやすくし、コードをより安全にします。

+0

これは素晴らしい提案です。残念ながら、「DoSomething()」は、それぞれのケースでは異なるもので、これらのアクションのすべてがこのインターフェースで意味をなさないわけではありません。また、おそらくの代替案は、非常に興味深く見えます。ありがとう。 –

関連する問題