| На данный момент существует множество технологий в Java мире, часто очень тяжело определится что же использовать. Данная тема создана для того, чтоб внести ясность в этот пестрый мир. Но прежде всего хотелось бы сказать следующее: многие попробовав тот или иной инструмент, стараются выразить свои мнения в духе "нет, это плохо, потому что.. " или "о, это хорошо, потому что...". Так вот здесь нет места таким мнениям. Я не устаю повторять, что всякий инструмент имеет свою нишу, кривые же руки не делают сам инструмент кривым. Конечно, если совсем неприятные наработки, но они не набирают популярность как правило, поэтому и обсуждаются очень редко. Итак, здесь мы будем говорить о том, какая технология в каком случае подходит. - Database access
- JDBC - в чистом виде используется не часто, потому как приходится писать очень много glue-кода, обычно реализовать проект с помощью JDBC довольно сложно и громоздко. Однако именно он поможет, когда вы захотите написать свой ORM ;) Также, JDBC довольно простой в использовании и не вынуждает вас тратить месяцы на его изучение. Работая с помощью JDBC вы имеете полный контроль над происходящим и соответственно максимальные возможности по тюнингу, что может помочь если у вас приложение очень высоконагруженное. С другой же стороны, вам придется писать SQL руками, вызывать его, работать с ResultSet'ами, самостоятельно реализовывать кеширование, маппинг ваших классов на реляционную модель (разные отношения: many-to-many, one-to-many, inheritance), кеширование на нескольких уровнях, поэтому стоит подумать трижды прежде чем писать приложение на чистом JDBC.
- iBatis/MyBatis - это надстройка над JDBC, которая делает за вас часть работы - она из ResultSet строит объекты. То есть сделали вы запрос к БД, указали какие поля в какие классы должны мапиться, а собственно сам процесс происходит за сценой. Этот фреймворк полезен, когда важна производительность, потому как вы сами будете создавать запрос к БД. Разработка с помощью iBatis происходит намного быстрей, чем с чистым JDBC, поэтому чаще всего, когда у вас стоит вопрос в производительности, но и скорость разработки тоже важна, то данный фреймворк - это то, что вам нужно. Из недостатков опять же - нужно самому писать и поддерживать схему БД и SQL. Фреймворк довольно прост в изучении
- ORM (object/relational mapping) - это фреймворки, которые позволяют совсем отгородится от реляционной БД, вы мапите объекты на схему БД, а затем просто говорите "сохрани сей объект" и он сохраняется без написания родных SQL команд.
ORM освобождает разработчика от многих обязанностей: работу с разными связями объектов на уровне реляционной БД, написание SQL команд, поддержание разных скриптом для разных СУБД если это требуется, как правило подключить кеширование к ORM'у очень просто, ничего самому делать не нужно, ну и в общем количество кода, который нужно написать, становится намного меньше, что улучшает читабельность проекта и его поддержку. Бывает, что ORM'ы работают быстрей, например, вы знали, что кеширование подготовленных запросов в DB2 JDBC Driver значительно повышает производительность, а в InterBase JDBC Driver наоборот - серьезно бьет по производительности? Вы знали, что в некоторых СУБД обновление только измененных колонок записи быстрей, а в других - медленней? ORM'ы это знают. Однако вы должны понимать, что работа напрямую с SQL может быть как минимум такой же эффективной, то есть чаще всего вы можете написать запрос или такой же по эффективности, или лучше. Это значит, что в общем ORM будет проигрывать приложению на том же JDBC или MyBatis. Еще одним недостатком ORM'ов является их сложность, чтобы ими пользоваться эффективно, нужно хорошо в них разобраться, что как правило занимает много времени (хотя с другой стороны по сравнению с изучением нескольких СУБД и их диалектов - это чепуха :)). Таким образом, когда вы выбираете что же использовать, перед вами стоит дилема - разработать продукт быстрей и с меньшим количеством трудозатрат, или разработать приложение, которое возможно будет работать эффективней. Я выбираю первый вариант всегда, когда это возможно. Однако когда речь идет об очень высоконагруженных приложениях, а также в вашей команде есть сильный DBA, то ORM скорей всего будет не лучшим выбором. - JPA2 (Java Persistent API) - это стандарт, который на данный момент (апрель 2011) входит в состав стандарта EJB3. Представляет собой набор аннотаций для маппинга сущностей на таблицы реляционной БД. Является только набором интерфейсов и аннотаций, реализаций всего этого добра довольно много: Hibernate, EclipseLink, реализации разных апп серверов. JPA имеет смысл использовать если вы хотите а) следовать стандартам в мире Java б) менять реализации JPA (например, для сравнения производительности или для написания библиотеки, которую можно будет использовать в других проектах и подставлять свои реализации). Однако часто чистого JPA не хватает, поэтому приходится использовать механизмы конкретной реализации, что уже само собой будет бить по переносимости.
- Hibernate - самый популярный Java ORM, который может использовать как аннотации (те, что входят в JPA, и дополнительные свои), а также XML. Если вам не критичны стандарты, если вы не собираетесь менять ORM'ы как носки, то удобно использовать Hibernate как отдельный продукт, а не как реализацию JPA. Это вам даст: а) много разных фич, которые не входят в JPA б) свободу выбора то ли это будут аннотации, то ли это будет XML. Замечу, что разработчики Hibernate активно участвуют в разработке JPA, однако в сам стандарт фичи попадают намного позже, поэтому если вам хочется использовать самые прогрессивные и современные фичи ORM'a, используйте Hibernate. Также он предоставляет два вида создания запросов: Criteria API, который удобен для создания динамических запросов, и HQL - hibernate query language, который напоминает SQL.
- JDO - изначально он разрабатывался как Java ORM standard, который может работать с любым data source (как БД, так и XML? так и что-то другое), однако особой популярности так и не приобрел. Однако он нужен, если вы собираетесь работать с Google App Engine. Чем он отличается от Hibernate: синтаксис запросов не SQL-подобный, а Java-подобный; после компиляции нужно запускать code enhancer, что добавляет еще один шаг в цикле разработки (хотя IDE имеют плагины, чтоб это делалось автоматически, ну и инструменты для сборки конечно это умеют), в то время как тот же Hibernate может работать в обеих режимах, как с enhancer'ом, так и без него. Опять же одного стандарта как правило мало, поэтому часто приходится использовать implementation-spefic механизмы; на самом деле отличий еще довольно много, для большего понимания читайте POJOs In Action.
- Сетевые протоколы - это протоколы для общения двух или нескольких приложений по сети, включая одно- и разно-родные языки/платформы. Они делятся на две группы: двоичные (скорость) и текстовые (читабельность).
- Google Protobuffers (Protobuf) - бинарный протокол, очень быстр. Имеет реализации под разные платформы, включая .Net, возможен RPC. Из недостатков - ограниченные возможности, к примеру, нет поддержки наследования (хотя есть обходные пути, но.. все ж не то). Из плюсов: имеет разные режимы, например, максимальная скорость, максимальное сжатие; можно писать так, чтоб в разных приложениях были разные (но при этом они должны быть совместимые) версии разметок. Для Java-Java общения разметку можно вообще не писать, причем в таком случае достигается максимальная скорость.
- ZeroC ICE - позволяет создавать разметку (Slice) в текстовом виде, затем из этой разметки генерить код (ммм. говнокод следует заметить), имеет реализации для многих языков. На практике встречались проблемы с .Net реализацией в многопоточном режиме, когда приложение просто висло, исправили это или нет - без понятия. Инструмент достаточно мощный, это целая платформа, которая позволяет создавать разноплатформенные Grid'ы. Обертки к примитивам не поддерживает (в принципе логично, не во всех языках наверно они есть), поэтому в крайнем случае нужно будет создавать свои классы-обертки и писать на разметку. Работает медленней Protobuf, места также занимают объекты больше, правда они выпустили поддержку Protobuf протокола. Однако поддерживается наследование, правда, из недостатков - все сериализуемые сущности должны реализовывать его собственный Object. Разметка достаточно некрасивая.
- Web
- Servlets API - представляет собой простой фреймворк для разработки веб приложений, подходит для любых приложений, используя Serlvets API можно сделать любой сайт, однако т.к. он представляет собой довольно низкую абстракцию, писать на нем крупные сайты довольно трудоемко, многое из того, что уже реализовано в Web MVC фреймворках, нужно реализовывать самому.
- JSF - это web mvc framework, который представляет собой компонентно-ориентированный MVC. Т.к. обычно в реализациях JSF довольно много готовых, часто используемых компонентов, то разрабатывать стандартные вещи довольно просто. Если же нужно что-то более изощренное, чем стандартные компоненты, то приходится их реализовывать самому, что не очень-то просто. JSF является хорошим решением, когда нужно написать веб приложение, которое должно индексироваться поисковиками, и при этом не хочется писать ни HTML, ни JavaScript. Многие жалуются на плохую производительность JSF фреймворков, однако вы не заметите различия если у вас не высоконагруженное приложение с точки зрения количества кликов.
- Spring MVC, Struts - это такие фреймворки, которые предоставляют готовую инфраструктуру с точки зрения обработки запросов, однако вид все равно придется писать самому, что включает в себя как HTML, так и JS. Если у вас есть верстальщики и/или вам нужно реализовывать нестандартные и изощренные эффекты и компоненты, то писать HTML и JS вам все равно придется, поэтому Spring MVC будет подходящим решением для вас, если JSF не подходит из-за недостатков, перечисленных выше.
- ZK, GWT, Vaadin - это такие Web MVC фреймворки, которые генерируют HTML и JS сами, при этом вы пишете что-то на Java, а они уже конвертируют это в нужную разметку. Т.к. эти фреймворки работают на AJAX, то они не годятся для случаев, когда нужно индексирование - никакие поисковики их не возьмут. Эти фреймворки подходят для внутренних или просто закрытых приложений (или их частей), где не нужно индексирование. С этими фреймворками можно сделать приятный и удобный интерфейс не написав ни строчки JavaScript'a вручную. ZK - очень быстр, но внутри страшных говнокод, дебажить и патчить такое - не благодарное дело. Vaadin наоборот создает впечатление медлительности, однако внутри просто няшка.
Большое отличие есть между ZK и GWT/Vaadin. У первого просто есть компоненты, которые часто общаются с сервером. Вторые же генерируют JavaScript (это один из шагов после компиляции приложения, причем не самый быстрый) и логика осуществляется в основном на клиентской стороне.
- Распределенные технологии
- Compute Grids - это те технологии, которые используются для сложных вычислений, когда нужно распаралелливать один запрос на много узлов.
- Apache Hadoop - из тех распределенных фреймворков, которые реализуют Map/Reduce алгоритм для обработки данных. Хадуп годится для сложной обработки огромных массивов данных. Например, Facebook использует его для парсинга логов, которых за день набирается по несколько терабайт. Выполнение любой задачи будет занимать не меньше нескольких секунд во-первых потому, что нужно время для распределения задач по узлам, во-вторых потому что все промежуточные результаты Hadoop сохраняет на жесткий диск, поэтому этот фреймворк не предназначен для ситуаций, когда ответ нужен мгновенный (такие как поиск по ключевым словам к примеру). По этим же причинам не годится для обработки в принципе маленьких задач, которые занимают секунды, ибо накладные расходы будут выше, чем трудозатраты на обработку задач. Обычно для использования Хадупа нужны гига-тера-пика-байты статических данных.
- Интеграционные решения
- Web Services - как правило их ниша сводится к открытым (реже - к закрытым) ресурсам, которые предоставляют платформо-независимый API. Например, у вас есть популярный сайт навроде соц. сети, к которому вы хотите сотворить API, чтоб разработчики во всем мире писали для него клиенты, плагины, чтоб кто угодно мог интегрироваться с вами. Это случай, когда стоит рассматривать веб службы - то ли SOAP, то ли REST. Есть два подхода писать SOAP WS, которые кардинально отличаются друг от друга:
- WSDL first - это когда вы пишете WSDL в виде XML, а затем генерируете java код по нему. Этот подход трудозатратен, но вы точно контроллируете контракт (wsdl файл) и выдаете наружу красивый файл. Следовать этому подходу имеет смысл, когда вы пишете публичный сервис, который будет использоваться кем угодно в сети, потому как принесет меньше головной боли тем, кто хочет использовать вашу службу.
- Code first - это когда вы пишете аннотированные классы, а затем генерируете WSDL по ним. В результате генерируется некрасивый, но рабочий, контракт. Этот способ, наверное, более распространен, ибо намного менее трудозатратен и в придачу работоспособен :) Поэтому для закрытых приложений, где возможно переиспользовать те же jar, или когда всем наплевать что там за контракт, они все генерируют, имеет смысл скорее использовать этот подход. Единственное - с веб службами не особо разберешься в деталях, если следовать code first. Еще одно но - генерируемый WSDL иногда бывает не переносим на другие платформы. Если .Net как правило будет работать с таким контрактом без проблем, то некоторые менее популярные платформы могуты выбрасывать ошибки типа "што за какашко, я такого не знаю", прежде чем выбирать этот подход убедитесь, что принимающая сторона точно будет понимать вас.
- MOM (message oriented middleware) - это решения типа JMS, которые как правило используются в закрытых корпоративных приложениях. Причины почему MOM выбирают в данном случае вместо WS:
- Нет необходимости в чем-то слишком универсальном, как правило внутри корпорации используется какая-то одна реализация MOM и никому не нужно это API выдавать наружу, где его будет использовать широкая мультиплатформенная публика.
- MOM надежен, т.к. сообщение не может не дойти (разве что сама MOM упала). Кроме того многими MOM поддерживается гарантированная доставка, которая может сохранять сообщения в постоянное хранилища типа БД вместо того, чтоб держать их в памяти как это делает обычная доставка, что значит, что сообщения не погибнут даже если MOM упало.
- MOM поддерживает pub/sub архитектуру. То есть сообщения могут рассылаться сразу многим подписчикам вместо одного, причем отсылающий может ничего не знать о том, кто его слушает.
- MOM позволяет доставлять сообщения даже если в данный момент приложение с другой стороны недоступно, - сообщение доставится как только сервер поднимется (называется Durable Subscription).
- MOM - это асинхронная модель, что значит, что отправитель отсылает сообщение и продолжает себе работать вместо того, чтоб ждать ответ в том же потоке. Такая асинхронная природа предоставляет много гибкости. Например, был выслан запрос на данные, ответ пришел через минуту, эти данные подхватились и затем клиент еще и ожидает обновлений если такие приходят. Это может поддерживаться только с помощью асинхронной архитектуры.
- С помощью MOM просто отсылать бинарные данные, они ничем не отличаются от обычных. Таким образом можно даже отсылать сериализованные Java объекты и десериализовывать их на другом конце.
- MOM поддерживают транзакционность - то бишь если мы отсылаем два сообщения двум разным получателям и хоть одно из них не дошло (например, второй подписчик в ауте счас), то транзакцию можно откатить будто сообщения не отсылались (на самом деле здесь возможны очень много опций и поведений).
- Apache Camel, Spring Integration - эти два фреймворка делают работу с MOM максимально приятной. Есть некие Enterprise Integration Patterns, которые описывают как можно использовать MOM, так вот эти фреймворки реализуют эти шаблоны и эту архитектуру. Они позволяют описывать маршруты, по которым должны ходить сообщения, задавать фильтры, перехватчики, трансформеры, реализовывать load balancing и failover и т.п. Однако это еще не все, они позволяют работать с разными видами транспорта, то бишь не только Messaging как таковой, но и.. например файловая система. Допустим вы получаете сообщение по WS, затем его нужно переслать другой системе по ActiveMQ, затем дождаться ответа и сохранить результат в файл; а если ответ не приходит в течение некоторого времени, то отсылать мейл администратору с ошибкой - весь этот маршрут можно задать с помощью данных фреймворков, причем все эти endpoint'ы будут работать с одной абстракцией - Message. В противном же случае вам бы пришлось а) работать напрямую с JAX-WS, JMS, JavaMail, IO и строить маршрут с помощью разных if-ов в Java коде. Пример XML based Camel, Пример Spring Integration.
Список будет постоянно пополняться. Если вы хотите услышать про какую-то определенную технологию/фреймворк/библиотеку, пишите в личку запросы. Предупреждаю, что не обязательно это выльется в какой-то результат, ибо описываю здесь только то, о чем знаю. Я не разбираюсь совсем в JS фреймворках, поэтому о них даже и не просите. |