2009-10-01 10 views
1

Je rencontre des problèmes avec l'utilisation de génériques en combinaison avec des hiérarchies de classes parallèles. Je me suis déjà codé plusieurs fois dans ce pétrin.Génériques et hiérarchies de classes parallèles

Disons que je les hiérarchies de classes suivantes: TableColumn -> sous-classes SqlTableColumn, OracleTableColumn Tableau -> sous-classes SQLTable, OracleTable Base de données -> subsclasses SqlDatabase, OracleDatabase

J'utilise des génériques sur les types de base, qui donne:

Table<TableColumn> 
Database<Table<TableColumn>> 

SqlTable<SqlTableColumn> 
SqlDatabase<SqlTable<SqlTableColumn>> 

OracleTable<OracleTableColumn> 
OracleDatabase<OracleTable<OracleTableColumn>> 

J'ai le sentiment que ce n'est pas un bon usage des génériques. Quel serait un meilleur design?

+0

langage de programmation (je suppose que Java ou C#)? – Jesper

Répondre

1

Les génériques (Java ou C#) sont vraiment destinés à prendre en charge les types paramétrés. Dans ce cas, les types que vous transmettez (TableColumn, SqlTableColumn) ne sont pas vraiment destinés à être des paramètres de type.

Je voudrais implémenter cet ensemble de types comme des hiérarchies d'objets parallèles, et non des types paramétrés. Par exemple:

OracleTable extends Table 
SqlTable extends Table 

OracleDatabase extends Database 
SqlDatabase extends Database 

OracleTableColumn extends TableColumn 
SqlTableColumn extends TableColumn 

Les méthodes publiques sur tous ces types doivent se référer uniquement aux classes de base, comme cela se fait dans JDBC, par exemple.

2

ignorant les choses théoriques derrière génériques sur quand les utiliser, cela me semble plus naturel (en C#):

class Database<T, C> 
    where T : Table<C> 
    where C : TableColumn { } 
class Table<C> 
    where C : TableColumn { } 
class TableColumn { } 

//sql 
class SqlDatabase : Database<SqlTable, SqlColumn> { } 
class SqlTable : Table<SqlColumn> { } 
class SqlColumn : TableColumn { } 

//oracle 
class OracleDatabase : Database<OracleTable, OracleColumn> { } 
class OracleTable : Table<OracleColumn> { } 
class OracleColumn : TableColumn { } 
Questions connexes