Bien que je sois totalement d'accord sur le point "Static n'est pas la bonne chose à utiliser ici", je comprends un peu ce que vous essayez d'aborder ici. Le comportement d'instance devrait être le meilleur moyen de travailler, mais si vous insistez, c'est ce que je ferais :
A partir de votre commentaire "J'ai besoin de créer une instance de celui-ci juste pour obtenir une chaîne qui est vraiment statique dans son comportement".
Ce n'est pas tout à fait correct. Si vous regardez bien, vous ne changez pas le comportement de votre classe de base, vous changez juste le paramètre d'une méthode. En d'autres termes, vous changez les données, pas l'algorithme.
L'héritage est plus utile lorsqu'une nouvelle sous-classe veut changer la façon dont une méthode fonctionne, si vous avez juste besoin de changer les "données" que la classe utilise pour fonctionner, une approche comme celle-ci ferait probablement l'affaire.
class ModelBase {
// Initialize the queries
private static Map<String,String> selectMap = new HashMap<String,String>(); static {
selectMap.put( "Album", "select field_1, field_2 from album");
selectMap.put( "Artist", "select field_1, field_2 from artist");
selectMap.put( "Track", "select field_1, field_2 from track");
}
// Finds all the objects for the specified class...
// Note: it is better to use "List" rather than "ArrayList" I'll explain this later.
public static List findAll(Class classToFind ) {
String sql = getSelectSQL( classToFind );
results = execute( sql );
//etc...
return ....
}
// Return the correct select sql..
private static String getSelectSQL( Class classToFind ){
String statement = tableMap.get( classToFind.getSimpleName() );
if( statement == null ) {
throw new IllegalArgumentException("Class " +
classToFind.getSimpleName + " is not mapped");
}
return statement;
}
}
En d'autres termes, faites correspondre toutes les déclarations avec un Map. La prochaine étape "évidente" est de charger la carte à partir d'une ressource externe, comme un fichier de propriétés, un fichier xml ou même (pourquoi pas) une table de base de données, pour plus de flexibilité.
De cette façon, les clients de votre classe (et vous-même) sont satisfaits, car vous n'avez pas besoin de "créer une instance" pour faire le travail.
// Client usage:
...
List albums = ModelBase.findAll( Album.class );
...
Une autre approche consiste à créer les instances à partir de l'arrière-plan, et à conserver l'interface client intacte tout en utilisant les méthodes d'instance, les méthodes étant marquées comme "protégées" pour éviter toute invocation externe. De manière similaire à l'exemple précédent, vous pouvez également faire ceci
// Second option, instance used under the hood.
class ModelBase {
// Initialize the queries
private static Map<String,ModelBase> daoMap = new HashMap<String,ModelBase>(); static {
selectMap.put( "Album", new AlbumModel() );
selectMap.put( "Artist", new ArtistModel());
selectMap.put( "Track", new TrackModel());
}
// Finds all the objects for the specified class...
// Note: it is better to use "List" rather than "ArrayList" I'll explain this later.
public static List findAll(Class classToFind ) {
String sql = getSelectSQL( classToFind );
results = execute( sql );
//etc...
return ....
}
// Return the correct select sql..
private static String getSelectSQL( Class classToFind ){
ModelBase dao = tableMap.get( classToFind.getSimpleName() );
if( statement == null ) {
throw new IllegalArgumentException("Class " +
classToFind.getSimpleName + " is not mapped");
}
return dao.selectSql();
}
// Instance class to be overrided...
// this is "protected" ...
protected abstract String selectSql();
}
class AlbumModel extends ModelBase {
public String selectSql(){
return "select ... from album";
}
}
class ArtistModel extends ModelBase {
public String selectSql(){
return "select ... from artist";
}
}
class TrackModel extends ModelBase {
public String selectSql(){
return "select ... from track";
}
}
Et vous n'avez pas besoin de modifier le code client, tout en bénéficiant de la puissance du polymorphisme.
// Client usage:
...
List albums = ModelBase.findAll( Album.class ); // Does not know , behind the scenes you use instances.
...
J'espère que cela vous aidera.
Une dernière remarque sur l'utilisation de List vs. ArrayList. Il est toujours préférable de programmer en fonction de l'interface plutôt que de l'implémentation, ce qui rend votre code plus flexible. Vous pouvez utiliser une autre implémentation de List qui est plus rapide, ou qui fait autre chose, sans changer votre code client.