質問: タイトルの通りでどちらが一般的でどういった使い分けを本当はするのかを教えてください。 下のfooとbarのイベントは自由で勝手なタイミングに起きるものとします。 1. fooイベントが発生すると処理Aを行う。このときCを作成する。 2. barイベントが発生すると処理Bを行う。このときCを使う。 Cが存在しないと処理BがおかしくなってしまうのでCの存在を保証したいです。そこで次の二つのどちらかを自分は今まで気まぐれで使っていました。 * 処理AでCを作成するまで、barイベントに処理Bを登録せずにおく * 処理Bの最初でCがあるかどうかを確認し、なければ処理を行わない 前者は無駄な確認処理がありません。後者は可読性が高いような気がします。 どちらを使うのが一般的なのでしょうか?それとも別の解決法があるのでしょうか?
回答: 一般的にどうなのかは分かりませんが・・・ 先に、もう一つの選択肢として、NullObjectパターンを提示しておきます。 例えばCが関数ならば、最初の時点では「何もしない関数」(=NullObject)をCに入れておいて、処理Aで正規の関数を入れ直す、という感じです。 『無駄な確認処理』が不要になるのが利点です。 以降は、私ならどうするか、ですが: > > 処理AでCを作成するまで、barイベントに処理Bを登録せずにおく > > > 処理Aにおける興味の中心が「処理Bのリスナ登録」であるなら、この方法を採ります。 逆に「Cの作成」であるなら、これは避けます。 私が前者の典型だと考えているのは、ドラッグ処理のイベントハンドリングです。 mousedownのイベントリスナでmousemove/mouseupのイベントリスナを登録、mouseupのイベントリスナでmousemove/mouseupのイベントリスナを解除、というコードはよく書きます。 この時、例えば「mousedownしたxy座標」のような、Cに相当するオブジェクトを作りますが、あくまで焦点はドラッグイベントの実現のためのイベント管理(登録/解除)であると考えます。 後者は、Cが処理B以外からも使用される場合などが該当します。 この場合は、 > > 処理Bの最初でCがあるかどうかを確認し、なければ処理を行わない > > > つまりnullチェックか、もしくはNullObjectパターンのどちらかを選択します。 この判断は微妙なのですが、プログラムの規模が大きいほど、NullObjectを使うことが多いです。 nullチェックをあちこちに書くと冗長ですし、チェックを忘れそうで怖いので。 すぐに全体を把握できるぐらい小さなプログラムで、チェックが一箇所しか無いなら、nullチェックで済ませると思います。