Obwohl ich absolut stimme in dem Punkt "Statische ist die falsche Sache hier zu verwenden", verstehe ich irgendwie, was Sie hier ansprechen wollen. Immer noch Instanz-Verhalten sollte die Möglichkeit zu arbeiten, aber wenn Sie darauf bestehen, ist das, was ich tun würde:
Ausgehend von Ihrem Kommentar "Ich muss eine Instanz erstellen, nur um eine Zeichenfolge zu erhalten, die wirklich im Verhalten ist"
Es ist nicht vollständig richtig. Wenn Sie gut aussehen, ändern Sie nicht das Verhalten Ihrer Basisklasse, sondern ändern nur den Parameter für eine Methode. Mit anderen Worten, Sie ändern die Daten, nicht den Algorithmus.
Vererbung ist nützlicher, wenn eine neue Unterklasse die Funktionsweise einer Methode ändern möchte. Wenn Sie nur die "Daten" ändern müssen, die die Klasse zur Arbeit verwendet, würde wahrscheinlich ein solcher Ansatz den Trick machen.
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;
}
}
Das heißt, alle Anweisungen mit einer Karte zuordnen. Der "naheliegende" nächste Schritt ist das Laden der Map aus einer externen Ressource, z. B. eine Eigenschaftendatei, oder eine XML-Datei oder sogar (warum nicht) eine Datenbanktabelle für zusätzliche Flexibilität.
Auf diese Weise können Sie Ihre Klassenkunden (und sich selbst) glücklich machen, weil Sie nicht "eine Instanz erstellen" müssen, um die Arbeit zu erledigen.
// Client usage:
...
List albums = ModelBase.findAll(Album.class);
...
Ein weiterer Ansatz ist die Instanzen von hinten zu schaffen, und halten Sie Ihre Client-Schnittstelle intakt, während Instanzmethoden verwenden, werden die Methoden als „geschützt“ gekennzeichnet externen Aufruf zu vermeiden ist. Auf ähnliche Art und Weise der vorherigen Probe können Sie dies auch
// 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";
}
}
Und Sie brauchen nicht den Client-Code zu ändern, und immer noch die Macht der Polymorphie haben.
// Client usage:
...
List albums = ModelBase.findAll(Album.class); // Does not know , behind the scenes you use instances.
...
Ich hoffe, das hilft.
Eine letzte Anmerkung zur Verwendung von List vs. ArrayList. Es ist immer besser, auf die Schnittstelle als auf die Implementierung zu programmieren, damit Sie Ihren Code flexibler gestalten. Sie können eine andere List-Implementierung verwenden, die schneller ist oder etwas anderes tut, ohne den Client-Code zu ändern.
Ich bin ein wenig verwirrt, warum Sie Ihre eigenen ORM schreiben, wenn es hervorragende Möglichkeiten wie iBatis und Hibernate gibt. Übrigens scheint es mir, dass Sie versuchen, eine statische Java-Methode wie eine Ruby-Klassenmethode funktionieren zu lassen. Wenn ja, wird es nicht funktionieren :( – Alan