2

一部のコンテナー クラスは、基本クラス "Table" (WoodenTable、MetalTable など) のオブジェクトのリストを保持します。各テーブル クラスは、その MaterialType (MaterialType.Wood、MaterialType.Metal...) を保持します。問題は、Table の各 SubClass を返すコンテナ クラスに適切な getter メソッドを提供する方法です。

これまでのところ、次の方法を見つけました。

1.マテリアルタイプをパラメータとするGetter。T の型が materialType に対応しない場合、ここで危険なのは ClassCastException です。

<T extends Table> T getTable(MaterialType materialtype)
WoodenTable table = getTable(MaterialType.Wood);
MetalTable table = getTable(MaterialType.Wood); // ups... exception

2.クラスパラメータを持つゲッター。安全ですが、ユーザーにとっては明確ではありません (パラメーターとしての MaterialType と比較して):

<T extends Table> T getTable(Class<T> tableClass)
WoodenTable table = getTable(WoodenTable.class);

3.各テーブル サブクラスのゲッター。新しいテーブル サブクラスを使用、作成、および追加するのが面倒です。

WoodenTable getWoodenTable()
WoodenTable table = getWoodenTable();

4.Table インターフェイスのみのゲッター。必要に応じて、コンテナ クラスの外で行われるキャスト。

Table getTable(MaterialType materialType)
WoodenTable woodenTable = (WoodenTable)getTable(MaterialType.Wood) 

それを行う他の(より良い)方法はありますか?そうでない場合、それらのうちどれが最も適切であるか、または臭いが最も少ないでしょうか?

4

2 に答える 2

0

テーブルを属性 (マテリアル) を持つデータ構造として考えるのをやめ、テーブルを「人」として扱い始めることをお勧めします (オブジェクト思考)。それらから「素材」を取得しないでください。代わりに、彼らの行動を公開させてください。

テーブルのデザインを変更すると、コンテナのデザインも自動的に変更されます。そして、コンテナはテーブルの素材を気にするべきではなく、テーブルがコンテナから出たいのか、そこにとどまるのかを制御できるようにする必要があることが明らかになります。

于 2012-12-31T14:06:08.937 に答える
0

それはちょうどこの単純なはずです:

public Table getTable()  
{  
     return this.table;
}  

Tableこれにより、呼び出し元が必要とする処理を行うオブジェクトが返されます。次のブロックに似ています。

public Collection<String> getCollection()  
{  
     return new ArrayList<String>();
}  

本体は を返しますArrayListが、関数は実際には を返しますCollection。オブジェクト間の最も一般的なインターフェイスを利用する明確に定義された API は、これと同じ柔軟性を提供します。

編集

はい、それは1つのユースケースかもしれませんが、多くの場合、 for(Table t : TableContainer) { (SubClassA)t.doSomethingSpecificForA();} のようなものも必要であり、それが私の問題の始まりです。

次のインターフェースと実装を想定してみましょう。

    public interface Table  
    {  
        Table getTable();  
        void doSpecial();  
    }


public class WoddenTable implements Table  
{  
     ...  
     public Table getTable()  
     {  
         return this;
     }    

     public void doSpecial()  
     {  
         mySpecial();  
     }  

     private void mySpecial()  
     {  
         System.out.println("Wooden");  
     }  
}    

public class MetalTable implements Table  
{  
     ...  
     public Table getTable()  
     {  
         return this;
     }    

     public void doSpecial()  
     {  
         mySpecial();  
     }  

     private void mySpecial()  
     {  
         System.out.println("Metal");  
     } 
}  

および次のコード:

public static void main(String[] args)  
{  
        Collection<Table> tables = new ArrayList<Table>();  
        tables.add(new WoodenTable());  
        tables.add(new MetalTable());  
        for(Table table : tables)  
        {  
              table.doSpecial();  
        }  
}  

ここでのアプローチは、共有パブリック API があることです。また、各クラスの内部は公開されていないため、各クラスに対して何かを行う必要性はspecial、共通インターフェイスの背後に隠されています。これにより、このタイプの問題を解決するためにチェックのインスタンスやその他の面倒な方法を実行する必要がなくなります。

于 2012-11-14T13:35:46.367 に答える