あなたの質問。
しかし、しかし-私の素朴さから、私に悲鳴を上げさせてください-時には価値が意味なく欠けていることがあります!
そこに完全に搭乗します。ただし、すぐに説明するいくつかの注意事項があります。でもまず:
ヌルは悪であり、可能な限り避けるべきです。
これは意図的だが一般化された声明だと思う。
ヌルは悪ではありません。それらはアンチパターンではありません。それらは、どんな犠牲を払っても避けるべきものではありません。ただし、nullはエラーになりやすい(nullのチェックに失敗するため)。
しかし、nullのチェックに失敗することは、nullが本質的に使用するのが間違っているという証拠です。
nullが悪なら、配列インデックスとC ++ポインターも同様です。そうではありません。彼らは自分の足で自分を撃つのは簡単ですが、決して避けられないはずです。
この回答の残りの部分では、「nullは悪」という意図をより微妙な「nullは責任を持って処理する必要があります」に適合させます。
あなたのソリューション。
nullをグローバルルールとして使用するというあなたの意見に同意しますが、この特定のケースでnullを使用することに同意しません。
以下のフィードバックを要約すると、継承とポリモーフィズムの目的を誤解していることになります。nullを使用するという議論には妥当性がありますが、他の方法が悪い理由のさらなる「証拠」は継承の誤用に基づいており、null問題とは無関係な点を示しています。
ほとんどのアップデートには当然プレイヤーが関連付けられています-結局のところ、どのプレイヤーがこのターンにどのプレイヤーを動かしたかを知る必要があります。ただし、一部の更新プログラムでは、意味のあるPlayerを関連付けることができません。
これらの更新が有意に異なる場合(異なる場合)、2つの個別の更新タイプが必要です。
たとえば、メッセージを検討してください。エラーメッセージとIMチャットメッセージがあります。ただし、非常によく似たデータ(文字列メッセージと送信者)が含まれている場合がありますが、同じようには動作しません。異なるクラスとして、別々に使用する必要があります。
あなたが今していることは、Playerプロパティのnull-nessに基づいて、2種類の更新を効果的に区別することです。これは、エラーコードの存在に基づいてIMメッセージとエラーメッセージを決定することと同じです。動作しますが、最良のアプローチではありません。
- JSコードは、定義されたプロパティとしてPlayerのないオブジェクトを受け取るだけです。これは、値が存在するかどうかを確認する必要があるため、nullの場合と同じです。
あなたの議論は、多型のミスに依存しています。あなたは返すメソッドがある場合はGameUpdate
、オブジェクトを、それは一般的に、これまでの間で区別する気にはならないGameUpdate
、PlayerGameUpdate
またはNewlyDevelopedGameUpdate
。
基本クラスには完全に機能するコントラクトが必要です。つまり、そのプロパティは派生クラスではなく基本クラスで定義されます(つまり、これらの基本プロパティの値はもちろん派生クラスでオーバーライドできます)。
これにより、議論が議論の余地がなくなります。良い習慣では、GameUpdate
オブジェクトにプレイヤーがいるかどうかは気にしないでください。aのPlayer
プロパティにアクセスしようとしGameUpdate
ている場合は、何か非論理的なことをしています。
C#などの型付き言語では、単にプロパティがないため、a のプロパティにアクセスしてアクセスすることさえできません。Javascriptはアプローチがかなり緩い(そしてプリコンパイルを必要としない)ので、あなたを修正することを気にせず、代わりに実行時に爆発する。Player
GameUpdate
GameUpdate
- 別のnull可能フィールドをGameUpdateクラスに追加する場合、この設計を続行するには多重継承を使用できる必要がありますが、MIはそれ自体が悪であり(経験豊富なプログラマーによると)、さらに重要なことには、C#はそうではありません持っているので使用できません。
nullableプロパティの追加に基づいてクラスを作成するべきではありません。機能的にユニークなタイプのゲーム更新に基づいてクラスを作成する必要があります。
一般にnullの問題を回避するにはどうすればよいですか?
価値の欠如を有意義に表現する方法について詳しく説明することは重要だと思います。これは、特定の順序でのソリューション(または不適切なアプローチ)のコレクションです。
1.とにかくnullを使用します。
これが最も簡単なアプローチです。ただし、大量のnullチェックにサインアップし、(失敗すると)null参照例外のトラブルシューティングを行います。
2. null以外の無意味な値を使用する
以下に簡単な例を示しますindexOf()
。
"abcde".indexOf("b"); // 1
"abcde".indexOf("f"); // -1
代わりにnull
、あなたは得る-1
。技術レベルでは、これは有効な整数値です。ただし、インデックスは正の整数であると予想されるため、負の値は無意味な答えです。
論理的には、これは、戻り値の型が意味のある戻り値よりも多くの可能な値を許可する場合にのみ使用できます(indexOf =正の整数; int =負および正の整数)
参照タイプの場合でも、この原則を適用できます。たとえば、整数IDを持つエンティティがある場合、nullではなく-1に設定されたIDを持つダミーオブジェクトを返すことができます。
オブジェクトが実際に使用可能かどうかを測定できる「ダミー状態」を定義する必要があります。
文字列値を制御しない場合は、事前に決められた文字列値に依存しないことに注意してください。空のオブジェクトを返したい場合は、ユーザーの名前を「null」に設定することを検討できますが、Christopher Nullがサービスにサインアップすると問題が発生します。
3.代わりに例外をスローします。
いいえ、ただ。論理フローでは例外を処理しないでください。
そうは言っても、(nullreference)例外を非表示にするのではなく、適切な例外を表示したい場合があります。例えば:
var existingPerson = personRepository.GetById(123);
これはPersonNotFoundException
、ID 123の人がいないときに(または同様の)をスローする可能性があります。
やや明らかに、これは、アイテムが見つからないためにそれ以上の処理ができない場合にのみ許容されます。アイテムが見つからない可能性があり、アプリケーションを続行できる場合は、例外をスローしないでください。これを十分に強調することはできません。