私のプロジェクトの1つでは、レコードタイプの抽象クラスを継承する2つの「データ転送オブジェクト」RecordType1とRecordType2があります。この "instanceof"オペレータの使用は悪い設計を考慮していますか?
両方のRecordTypeオブジェクトを、同じRecordProcessorクラスで "process"メソッド内で処理する必要があります。
public RecordType process(RecordType record){
if (record instanceof RecordType1)
return process((RecordType1) record);
else if (record instanceof RecordType2)
return process((RecordType2) record);
throw new IllegalArgumentException(record);
}
public RecordType1 process(RecordType1 record){
// Specific processing for Record Type 1
}
public RecordType2 process(RecordType2 record){
// Specific processing for Record Type 2
}
私はスコット・マイヤーズは、以下で効果的なC++を書き込む読んだ:私の最初に考えたのは、2つの特定のプロセスメソッドに委譲を次のように汎用的な処理方法を作成することでした
「いつでもあなたオブジェクトのタイプがT1の場合はフォームのコードを記述してから、何かを実行しますが、タイプがT2の場合は他の操作を行います。
もし彼が正しければ、私は自分自身を叩いているはずです。私は実際にこれが悪いデザインであることは実際には分かりません(もちろん、誰かがRecordTypeをサブクラス化し、それを扱うジェネリックの "Process"メソッドに別の行を追加せずにRecordType3を追加しないとNPEを作成しません)理論的にはこれらのレコードで実行したい多くの異なるタイプの処理が可能なので、実際には私にはあまり意味がありません。
これは悪い設計とみなされる理由を説明し、これらのレコードを処理中のクラスに処理する責任を引き続き与える何らかの代替手段を提供できますか?
UPDATE:だけ明確にするthrow new IllegalArgumentException(record);
return null
を変更
- 、シンプルRecordType.process()メソッドは十分ではない三つの理由があります:まず、処理は本当にあまりにも遠くに除去されますRecordTypeのサブクラスで独自のメソッドを使用できるようにするためです。また、理論的には異なるプロセッサによって実行されることができる、異なるタイプの処理の完全なスルーが存在する。最後に、RecordTypeは、内部で定義された最小限の状態変更メソッドを持つ単純なDTOクラスとして設計されています。
通常、悪い兆候です。しかし、あなたがしようとしていることを理解する必要があります。それは疑問からは分かりません。一般的には、すべてのタイプが同じ機能を持っているようですので、インターフェイスを使用することができます – Yossale
RecordType1と2の違いは何ですか?おそらくそれらを同じインターフェースに従わせることができますか? – kba
あなたは一般的にそれをしたくありませんが、論理が一度しか表示されていない場合は、おそらくあなたはそれを使っています。複数の場所で表現された同じ 'if(instanceof X)'ロジックを見てみると、本当に自分自身を叩かなければならないときです。 –