У меня есть два класса для работы с mysql (прога десктопная, поэтому без ORM'ом). Была мысль, сделать еще один — синглетон, который будет сначала подключаться к БД при первом вызове, а потом уже эти два класса будут его использовать. Но подключение к БД хочется делать снаружи, а потом уже в него передавать. Ну и в общем, вместо синглетона я сделал вот так, и мне интересно, насколько это плохо и почему.
public class Database {
private static Boolean ready = false;
private static Connection con = null;
public Database() {
}
public static void init(Connection connection) throws Exception {
if (ready == false) {
if (con != null) {
con = connection;
ready = true;
// тут будут создаваться таблицы, если их нет
} else {
throw new Exception("connection == null");
}
} else {
throw new Exception("ready == true");
}
}
public static void destroy() {
con = null;
ready = false;
// тут будет закрываться соединение
// и вообще всё, что можно закрыть
}
// все остальные (тоже static) методы с запросами,
// выбрасывающие эксцепшны, если ready == false
}
Здравствуйте, fegdri, Вы писали:
F>У меня есть два класса для работы с mysql (прога десктопная, поэтому без ORM'ом). Была мысль, сделать еще один — синглетон, который будет сначала подключаться к БД при первом вызове, а потом уже эти два класса будут его использовать. Но подключение к БД хочется делать снаружи, а потом уже в него передавать. Ну и в общем, вместо синглетона я сделал вот так, и мне интересно, насколько это плохо и почему.
F>...
F>Я нормален? Посоветуйте что-нибудь.
Ты лучше опиши, какие именно цели преследует использование подобного класса.
Пока видно следующее:
Нет смысла использовать wrapper type Boolean, если везде по контексту он используется как boolean; 'if (ready == false)' ==> 'if (!ready)'; 'throw new Exception()' ==> стоит использовать более специфичный подкласс;
Error message в бросаемых исключениях не очень поможет человеку, не знакомому с кодом, понять, в чем проблема;
Нет смысла в public конструкторе, если класс содержит только статические методы;
Нет закрытия коннекшна и ресурсов, выделенных им (statements, result sets);
Нет поддержки многопоточности (и race condition, и safe publication); 'прога десктопная, поэтому без ORM'ом' — применимость orm не связана с этим;
DZ>Нет смысла использовать wrapper type Boolean, если везде по контексту он используется как boolean;
Буду знать.
DZ>'throw new Exception()' ==> стоит использовать более специфичный подкласс;
Я очень спешил.
DZ>Error message в бросаемых исключениях не очень поможет человеку, не знакомому с кодом, понять, в чем проблема;
И как тогда как? Плодить тысячу классов эксцепшнов?
DZ>Нет закрытия коннекшна и ресурсов, выделенных им (statements, result sets);
Коннекшн я собирался закрывать в дестрое, а всё остальное вроде бы проще открывать-закрывать прямо на месте. Ну т.е., стейтмент открыл, сделал один-два запроса, закрыл (прямо в одном методе всё).
DZ>'прога десктопная, поэтому без ORM'ом' — применимость orm не связана с этим;
Не знаю, откуда у меня такое предубеждение. Но толком ORM'ами пользоваться не умею. Как впрочем и языком.
DZ>какие именно цели преследует использование подобного класса.
Это самое интересное. Мне просто лень было при вызове конструкторов двух других классов писать лишние буквы в параметрах. Но я в общем уже всё переделал. Теперь у меня там обычный класс, не статик. Такая вот история.
... DZ>>Error message в бросаемых исключениях не очень поможет человеку, не знакомому с кодом, понять, в чем проблема;
F>И как тогда как? Плодить тысячу классов эксцепшнов?
Здравствуйте, fegdri, Вы писали:
DZ>>'прога десктопная, поэтому без ORM'ом' — применимость orm не связана с этим;
F>Не знаю, откуда у меня такое предубеждение. Но толком ORM'ами пользоваться не умею. Как впрочем и языком.
Насколько я понимаю, то в случае Hibernate (и, похоже, других ORM) будет проблема с hibernate-сессиями. В web-приложении hibernate-сессия открывается при начале запроса и закрывается после окончания обработки. В какой момент открывать/закрывать сессию в dekstop приложении — нужно думать.
Здравствуйте, LeonidV, Вы писали:
LV>Насколько я понимаю, то в случае Hibernate (и, похоже, других ORM) будет проблема с hibernate-сессиями. В web-приложении hibernate-сессия открывается при начале запроса и закрывается после окончания обработки. В какой момент открывать/закрывать сессию в dekstop приложении — нужно думать.
Session per-request далеко не единственный подход к работе с hibernate (см., например, long conversations).
Задача выбора способа управления сессиями в standalone application принципиально ничем не отличается от задачи выбора способа управления сессиями на сервере, разве что в первом случае возможностей больше, т.к. не надо закладываться на специфичный протокол общения клиента и сервера.
Здравствуйте, fegdri, Вы писали:
DZ>>Нет закрытия коннекшна и ресурсов, выделенных им (statements, result sets);
F>Коннекшн я собирался закрывать в дестрое, а всё остальное вроде бы проще открывать-закрывать прямо на месте. Ну т.е., стейтмент открыл, сделал один-два запроса, закрыл (прямо в одном методе всё).
А вот про это по-подробнее. Если ты про finalize() — то переопределять этот метод не стоит без глобальной надобности.
Здравствуйте, fegdri, Вы писали:
F>У меня есть два класса для работы с mysql (прога десктопная, поэтому без ORM'ом). Была мысль, сделать еще один — синглетон, который будет сначала подключаться к БД при первом вызове, а потом уже эти два класса будут его использовать. Но подключение к БД хочется делать снаружи, а потом уже в него передавать. Ну и в общем, вместо синглетона я сделал вот так, и мне интересно, насколько это плохо и почему.
F>Я нормален? Посоветуйте что-нибудь.
Попробуйте хотя бы сформулировать конкретную роль этого класса. Кроме флага ready никакой полезной логики в нем нет. Так же он зачем-то должен закрывать соединение, которого не создает.
Даже на десктопе зачастую нужно иметь хотя бы 2 активных соединения. Вы же просто таким образом убиваете все потенциальные возможности расширения приложения либо в серверный код, либо в другую многопоточную среду.
static плох именно тем что отрицает возможность заиметь два экземпляра. В вашем случае как раз там где вероятность необходимости нескольких экземпляров велика.
Почему public конструктор?