0

さまざまなコンストラクターを持つ DataSet というクラスがあり、それぞれが異なる型の変数を指定しています。次のようになります。

public class DataSet
{
    private HashSet Data;


    public DataSet( DataObject obj )
    {
        Data = new <DataObject>HashSet();
        Data.add( obj );
    }

    public DataSet( ObjectRelationship rel )
    {
        Data = new <ObjectRelationship>HashSet();
        Data.add( rel );
    }
    // etc.

注: 不完全な部分があるため、そのコードをまだテストしていません (現在作成中です)。

現在作成中の関数ではgetDataObjects()、このセットが表すすべての DataObject オブジェクトを返す必要があります。クラスの HashSet を開始するコンストラクターの場合、(上記の など)Data以外の型で、その中に格納されている DataObjects は明らかに存在しません。この場合、HashSet 'Data' が開始されたタイプを検出できる必要があります ('ObjectRelationship' であるかどうかを判断するなど)。どうすればいいですか? tl;dr : コレクション (この場合は HashSet) がコード内で開始されたことを型に伝えるにはどうすればよいですか ('if' または 'switch' ステートメントなどを使用)。DataObjectObjectRelationship



4

8 に答える 8

4

クラス全体をジェネリックにしたいようですね。クラスの宣言にテンプレート パラメーターを追加し、型のテンプレート パラメーターを使用して HashSet と検索関数を定義します。

私は現時点では .Net を使用しているため、Java 構文を示すことはできませんでしたが、C#構文を使用すると、次のようになります。

public class DataSet<T>
{
    private Set<T> Data;

    public DataSet( T obj )
    {
        Data = new HashSet<T>();
        Data.add( obj );
    }

    public Iterator<T> getDataObjects()
    {
        return Data.iterator;
    }
}
于 2008-12-26T15:12:42.690 に答える
1

セットからオブジェクトをフェッチして、そのタイプを検証できます。

または、異なるタイプを含む複数のセットを持つこともできます。

または、クラス型のインスタンス変数をインスタンス変数として弁別器として機能させることもできます。

または、最後の手法を使用して HashSet のプロキシ オブジェクトを作成することもできます。

于 2008-12-26T14:56:31.583 に答える
1

設計を再考する必要があるようです。

また、ジェネリックについて明確にするために。実行時に型にアクセスすることはできません。型パラメーターはコンパイル時のチェック専用であり、実行時に完全になくなります (型消去)。

于 2008-12-26T18:08:41.570 に答える
1

セットへのマップを使用できます

HashMap <Class<?>, HashSet<Object>> data;
HashSet temp = data.get(DataObject.class);
if(temp == null)
{
   temp = new HashSet();
   data.put(DataObject.class, temp);
}
temp.add(obj);

そうすれば、両方の長所を活かすことができます。

于 2008-12-26T16:45:04.577 に答える
0

DataObjectがオブジェクトの上に何を提供するのかわかりません。

あなたの問題に対するオブジェクト指向のアプローチは、あなたの興味のあるドメイン(例えば、請求書、顧客など)を反映したクラスを使用すると思います。永続層は永続の詳細を隠します。

これを実現する一般的な方法は、データアクセスオブジェクトを使用することです。これは、Javaでは次のようになります。

public interface GenericDao<T>
{
    T find(Serializable id);
    List<T> find();
    void save(T obj);
    void update(T obj);
    void delete(T obj);
}

これで、リレーショナルデータベースを模倣するものではなく、オブジェクトを処理することになります。CRUDの詳細はすべてDAOインターフェイスの背後に隠されています。

于 2008-12-26T17:38:08.340 に答える
0

このクラスは、CachedRowSet が提供しないものを提供しますか?

申し訳ありませんが、これはあまり良い抽象化ではないと思います。私があなたのチームのメンバーだったら、私はそれを使用しません。

あなたの構文も私には正しく見えません。IntelliJ は私に同意します。コンパイルされません。

これは次のことを行います。

import java.util.HashSet;
import java.util.Set;
import java.util.Arrays;

public class DataSet
{
    private Set<DataObject> data;


    public DataSet(DataObject obj)
    {
        this.data = new HashSet<DataObject>();
        data.add(obj);
    }

    public DataSet(DataObject[] objs)
    {
        data = new HashSet<DataObject>();
        data.addAll(Arrays.asList(objs));
    }
    // etc.
}

まだ抽象化が不十分です。考え直してください。

于 2008-12-26T14:58:21.767 に答える
0

ハッシュセットの初期化に使用されたタイプを指定するプロパティをデータセット クラス (列挙値、ブール値、またはタイプ) に追加できます。

適切なコンストラクターでプロパティを設定します。これにより、コレクションから要素を取得してその型をチェックすることを回避できます。

疑似コード:

public class DataSet
{
private HashSet Data;
private Type _iw = null;
public Type InitializedWith { return _iw; }

public DataSet(DataObject)
{
...
_iw = typeof(DataObject);
}

public DataSet(ObjectRelationship)
{
...
_iw = typeof(ObjectRelationship)
}
于 2008-12-26T15:05:41.580 に答える
0

ダフィーモのアドバイスに従い、より良い抽象化を使用します。このばかげた問題を回避できるように、使用する予定の特定のタイプごとに複数のクラスを作成します (それぞれが共通のインターフェイスを実装します)。

正しい型の各 DataSet オブジェクトを作成するプロセス中に、わずかなオーバーヘッドが追加されますが、それはまさにその通りだと思います。

于 2008-12-26T16:22:44.390 に答える