2016-09-03 8 views
0

Heres a design question。 Fooオブジェクトのマップをスーパークラスに格納し、より特定のオブジェクトにルックアップをキャストするのは悪い習慣でしょうか?すなわち:スーパータイプのマッピングとサブタイプの取得

Map<Integer, Foo> lookup = new HashMap<>(); 
lookup.put(0, new Bar()); //Bar extends Foo 
lookup.put(1, new Fizz()); // Fizz extends Foo 

public Bar getBarById (int barId){ 
    (Bar)lookup.get(barId); 
} 

上記のアプローチはどのように脆弱でしょうか? Java8でより良い方法があるのか​​、それとも私が似たようなことをするためのより良いデザインパターンがありますか?

+0

答えは、オブジェクトが使用され、なぜあなたがそれらを保存しているかに依存します。たとえば、オブジェクトが使用したい標準インターフェースを実装している場合は、そのインターフェースをMap値の型に使用し、型キャストを心配する必要はありません。 –

+0

ルックアップの後の@JEarlsルックアップオブジェクトのフィールドにアクセスしたいです。インターフェイスにこれらのメソッドがすべて含まれているわけではありません。たとえば、クラスバーだけがgetname()を持っていたので、そのメソッドを使用する前に型を知る必要がありました –

+0

どの代替手段と比較しましたか? – Holger

答えて

0

これはいい考えですが、オブジェクトを分割する必要があるようです。自分のキーを追跡する場合を除いて、マップからどのタイプを引き出すのかはわかりません。

キー0で新しいBar()を入力すると、そのオブジェクトをリストなどに保存する必要があります。そのため、Barのメソッドを呼び出す場合は、BarオブジェクトIDのArrayListを見ることができます。

Map<Integer, Foo> lookup = new HashMap<>(); 
ArrayList<Integer> listOfBar = new ArrayList<>(); 
ArrayList<Integer> listOfFizz = new ArrayList<>(); 

lookup.put(0, new Bar()); //Bar extends Foo 
listOfBar.add(0); 

lookup.put(1, new Fizz()); // Fizz extends Foo 
listOfFizz.add(1); 

//in Method to return Bars 
if(listOfBar.size() != 0){ 
int k = listOfBar.get(0); 
Bar b = lookup.get(k); 
return b; 


} 

したがって、特定のオブジェクトのすべてのIDは、arraylistを使用してアクセスできます。

あなたはそれを「フィズ」(あなたの例では、ID#1)のIDを与えるとき getBarbyId()が失敗するので、元のコードは動作しません
0

// ClassCastException: System.out.println(this.getBarById(1).getClass().getSimpleName()); 

あなたが達成できましたArrayListの場合と同じことですが、重要な点は、Fooクラスを変更することができない場合でも、独自のアクセサーが必要な場合はgetFooByIdにする必要があるということです。

例:

import java.util.ArrayList; 

public class Main { 
    class Foo { 
     // Assume defined elsewhere and we can't change it 
    } 

    class Bar extends Foo {} 
    class Fizz extends Foo {} 

    public Foo getFooById(int id) { 
     return fooList.get(id); 
    } 

    ArrayList<Foo> fooList = new ArrayList<>(); 

    Main() { 
     fooList.add(0, new Bar());  // keys optional here, unless you are 
     fooList.add(1, new Fizz());  // looking for specific entries later 

     for (int i=0; i < fooList.size(); i++) { 
      System.out.println("foo: " + i + " " + getFooById(i).getClass().getSimpleName()); 
     } 
    } 


    public static void main(String[] args) { 
     Main m = new Main(); 
    } 
} 

出力:

foo: 0 Bar 
foo: 1 Fizz 
関連する問題