Хотя я полностью согласен с тем, что «Static - это не то, что нужно использовать здесь», я как бы понимаю, что вы пытаетесь решить здесь. И все-таки поведение экземпляра должно быть способом работы, но если вы настаиваете, что это то, что я сделал бы:
Начиная с вашего комментария «Мне нужно создать экземпляр, чтобы получить строку, которая действительно статична в поведении»
Не совсем верно. Если вы выглядите хорошо, вы не изменяете поведение своего базового класса, просто изменяя параметр для метода. Другими словами, вы меняете данные, а не алгоритм.
Наследование более полезно, когда новый подкласс хочет изменить способ работы метода, если вам просто нужно изменить «данные», которые использует класс для работы, вероятно, такой подход мог бы сделать трюк.
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;
}
}
То есть сопоставьте все заявления с картой. «Очевидным» следующим шагом является загрузка карты из внешнего ресурса, такого как файл свойств, или xml или даже (почему бы и нет) таблицы базы данных для дополнительной гибкости.
Таким образом, вы можете поддерживать клиентов класса (и себя) счастливыми, потому что вам не нужно «создавать экземпляр» для выполнения работы.
// Client usage:
...
List albums = ModelBase.findAll(Album.class);
...
Другой подход заключается в создании экземпляров из-за, и сохранить свой клиентский интерфейс неповрежденной при использовании методов экземпляра, методы помечены как «защищенный», чтобы избежать внешнего вызова. Подобным же образом в предыдущем примере вы также можете сделать это
// 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";
}
}
И вам не нужно, чтобы изменить код клиента, и до сих пор имеют силу полиморфизма.
// Client usage:
...
List albums = ModelBase.findAll(Album.class); // Does not know , behind the scenes you use instances.
...
Я надеюсь, что это помогает.
Последняя заметка об использовании списка против ArrayList. Всегда лучше программировать интерфейс, чем реализацию, таким образом, вы делаете свой код более гибким. Вы можете использовать другую реализацию List, которая выполняется быстрее или делает что-то еще, без изменения кода клиента.
Я немного озадачен, почему вы пишете свою собственную ОРМ, когда есть отличные варианты, такие как iBatis и Hibernate. Кстати, мне кажется, вы пытаетесь заставить статический метод Java работать как метод класса Ruby. Если это так, это не сработает :( – Alan 2008-09-30 05:51:27