エラーが起きたことをエラーコードで表現していると、エラーコードの伝播処理が大変になることがある。ある関数でエラーが起きたとき、エラーコードをreturnし、上位でエラー処理を行う。そこでエラー処理しない場合はさらに上へエラーコードをreturnしなくてはならない。このようにエラーコードを返す処理をいろんな関数に組み込まなくてはならなくなってしまう。そこでエラーコードの代わりに例外を使ってエラー処理を行う。
public Data makeData(String dataname) { Data newData; // データ作成処理 ... if (データ作成に失敗した?) { return null; } return newData; }
あるゲーム中で使うデータを動的に作成するメソッドがあり、データ作成に失敗したらnullを返すようにしてあるとする。これを例外処理に置き換えると次のような感じになる。
public Data makeData(String dataname) throws MakeDataErrorException { Data newData; // データ作成処理 ... if (データ作成に失敗した?) { throw new MakeDataErrorException(dataname); } return newData; }
データ作成に失敗したときに例外を投げる。受け取る側ではtry...catchで受け取る。
public void func(dataname) { try { Data newData = makeData(dataname); } catch (MakeDataErrorException e) { // データ作成に失敗したときのエラー処理 } }
エラーコードを例外で置き換えるのには、まず適切な例外を作ることが重要。そもそも例外的な事態でないなら例外で処理すべきでない。例外的な事態でも回復可能なのか、回復不可能なのかによっても異なる。回復可能な例外なら、throws節をつけ、エラーが起きたときにthrowで投げ、try...catchで受け取り処理を行う。回復不可能な例外の場合はそれが起きないように事前にチェックすべきである。
さて、ゲームにおいて例外で処理するような場合ってどんな状況があるか考えてみた。
まずは読み込むべきファイルが見つからない場合。そのときは「ファイルがありません」ってメッセージを出すくらいか。あとはネットワーク対応ゲームでネットワークがタイムアウトした場合とか。あとはあんまり思いつかないなぁ。
そもそも例外がおきるような状態になってしまっては、ゲームを進行させることが困難で復帰できないだろう。ゲームでは例外的な事態は出さないようにすべきだろう。
どうも個人的には例外処理って苦手である。