12

私は現在、Java インターフェイスとジェネリックを使用して概念モデルの API を実装しようとしています。このモデル (Transmodel V5.0) は、エンティティー関係モデルとして詳細に記述されていますが、使用される基本タイプの一部が指定されていません。たとえば、さまざまなエンティティの識別子のタイプや、シーケンス内の順序付けを確立するために使用されるタイプは定義されていません。

API を可能な限りジェネリックに保ちたいので、ジェネリックを使用してそれらの詳細を構成するようになりました。何かが一貫していると仮定しないことを含め、型について仮定をしたくありません。各エンティティは異なる識別子タイプを持つことができ、各シーケンスは順序付けのために使用される異なるタイプを持つことができます。

私が直面している問題は、あるエンティティが別のエンティティを参照すると、複雑さが急速に増大することです。その識別子の型を渡す必要があるだけでなく、参照されるエンティティを構成するために必要なすべてのものも必要です。

たとえば、私は持っています:

/**
 * @param <ID> The type for the identifier of this entity.
 * @param <ID_JP> The type identifying journey patterns.
 * @param <OP_JP> The ordering used for points in journey patterns.
 * @param <JP> The type of journey pattern referenced by this entity.
 */
public interface VehicleJourney<
        ID,
        ID_JP, OP_JP extends Comparable<OP_JP>, JP extends JourneyPattern<ID_JP, OP_JP>
    > extends IdentifiableObject<ID>
{
    JP getJourneyPattern();
}

私はまだそれを読んで意味をなすことができますが、少し冗長になってきています。そして、VehicleJourney のようなエンティティを他のエンティティで参照できるため、型パラメーター リストが爆発的に増加します。これは、私が考えることができる最小の重要な例です。

型システムの構成全体をモデル化する単一の Java エンティティを作成する方法はありますか? 私は、すべての識別子タイプと順序付けタイプをアタッチし、1 つとして渡すことができるものを考えています。上記の例を次のようにします。

public interface VehicleJourney<CONF, JP extends JourneyPattern<CONF>> 
       extends IdentifiableObject<???>
{
    JP getJourneyPattern();
}

疑問符のある場所では、VehicleJourney 識別子のタイプを CONF から何らかの方法で抽出する必要があります。それが実現可能であれば、複雑さは管理可能なレベルにとどまるはずです。

4

1 に答える 1

1

きれいにはなりません。

固定されていない型を使用し、id とコンパレータの型をグループ化する型を使用して単純化できます。

public interface Meta<ID, COMP extends Comparable<COMP>> {

}

public interface IdentifiableObject<M extends Meta<?, ?>> {

}

public interface JourneyPattern<M extends Meta<?, ?>>
        extends IdentifiableObject<M> {

}

public interface VehicleJourney<M extends Meta<?, ?>, JP extends JourneyPattern<?>>
        extends IdentifiableObject<M> {

}

型のネストされた型を固定するために名前を付ける必要はありません。具象クラス (またはサブインターフェイス) がある場合、すべての型が固定されます。例えば:

public class VehicleJourneyImplMeta implements Meta<String, String> {

}

public class VehicleJourneyImpl extends IdentifiableObjectBase<VehicleJourneyImplMeta> 
        implements VehicleJourney<
                VehicleJourneyImplMeta, 
                JourneyPattern<Meta<Integer, String>>> {

}

中間クラス (おそらく匿名クラス) を使用して、Meta の型へのアクセスを委任する必要があります。

VehicleJourney<Meta<String, String>, ?> v = something();
Meta<String, String> m = v.getObjectMeta();
String idOfV = m.getId();

メソッド レベルでのさまざまな型パラメーターの助けを借りて、おそらくこれを機能させることができます。

あなた (そして私、そしてほとんどの人) が本当に望んでいるのは、次のようなものだと私には思えます:

public interface VehicleJourney<M extends Meta<?, ?>, JP extends JourneyPattern<?>>
        extends IdentifiableObject<M> {

        public JP.M.ID getIdOfReferencedX();
}

JP.M.ID残念ながら、Java は戻り値の型として型付けをサポートしていません。多分誰かがこれのために JSR を上げるでしょう。私の記憶が正しければ、バイトコードにはジェネリック型パラメーターの名前が含まれています。

于 2014-01-31T05:34:33.103 に答える