Date: 03/29/07 (Code WTF) Keywords: java Недавно смотрел один большой кусок Java EE кода, в котором было много мелких приколов, которые затеняются двумя «гениальными» архитектурными решениями. … new AdminConsoleFrame(adminInterfaceWrapper); …Класс AdminConsoleFrame расширяет JFrame. Объект adminInterfaceWrapper врапит ссылки на EJB-ухи. В конструкторе AdminConsoleFrame после создания компонентов выполняется setVisible(true). Java EE сервер, в котором это запускалось, на Windows Server 2003 обычно работает как сервис. А в сервисах на Windows нельзя работать с сетью и показывать окошки одновременно. Так что авторы получили мягкий намек на то, что они делают что-то не то. Однако, намек был проигнорирован. В документации было сказано, что если хотите иметь AdminConsole, пускайте из командной строки и точка. Мне понадобилось несколько часов, чтобы просто поверить, что они действительно создают Swing-овое окошко из сервлета. Самое смешное, что я так и не смог вспомнить хотя бы один источник, где бы говорилось, что этого делать нельзя. Что новые потоки запускать нельзя, это было. А вот что бы говорилось, что Swing-овые окошки из сервлетов пускать нельзя, вот этого я не помню. Второй прикол связан с EJB. У меня вознкло такое чувство, что где-то они прочитали, что локальные EJB это хорошо, и что сессионные EJB это плохо. Соответственно, в приложении у них есть только сервлеты (включая AdminConsole) и entity EJB (с локальными интерфейсами). Entity EJB - вполне традиционные. Есть куча setter и getter методов. Какой-либо бизнес логики не наблюдается. Так же есть методы создания и поиска на home интерфейсах. Если не использовать Spring или что-то подобное, в такой ситуации обычно используется UserTransaction. Однако эти гении решили, что это не их путь. Они пометили все методы на EJB как «transaction required» и не стали «загромождать код» использованием UserTransaction. В результате, в коде, напрямую вызываемом из сервлетов и AdminConsole, есть куча мест вроде этого: … Account account =accounts.findByPrimaryKey(userid); Float balance = account.getBalance(); if (balance == null) throw new BusinessLogicException(); float newAmount = balance.floatValue() - price.floatValue(); account.setBalance(new Float(newAmount)); … Purchase purchase = purchases.create(itemid); purchase.setAccount(account); …Использование Float для хранения денег в финансовом приложении это отдельный WTF. Но основная проблема не в этом. Приведенный код работает в режиме, похожим на режим «autocommit» в базах данных. На каждое взаимодействие с EJB, создается отдельная транзакция. То есть, в приведенном коде будут выполнены пять транзакций (если все пойдет хорошо). В результате, получить базу в некорректном состоянии, это раз плюнуть. Например, деньги могут быть вычтены, а товар не добавлен. Я уже молчу про производительность. На данном примере хорошо видно, что знать спеки это одно, а практические знания, это совсем другое. Формально, спекам они почти не противоречат. Но по факту, код сплошной WTF. Source: http://community.livejournal.com/code_wtf/77025.html
|