IBM®
Перейти к тексту
    в России и странах СНГ [изменить]    Условия использования
 
 
   
    Главная страница    Продукты    Услуги и решения    Поддержка и загрузка    Мой профиль    
Перейти к тексту

developerWorks Россия  >  WebSphere | Технология Java  >

EJB Advocate: Правильное получение перекрестных ссылок EJB

developerWorks
Опции документа

Опции документа, требующие включения JavaScript, не отображаются

Обсудить


Выскажите мнение об этой странице

Помогите нам улучшить содержание


Уровень сложности: простой

Джефф Хэмбрик, инженер, IBM

18.02.2008

Попытка разработчиков исключить использование EJB-компонентов может привести к дублированию списков ссылок, нарушению инкапсуляции и к головной боли при обслуживании. EJB Advocate пытается облегчить проблему, показывая, как расширить функциональность сессионных EJB-компонентов на распространение, транзакции и систему защиты, а также демонстрируя, как EJB-компоненты помогают сделать приложения более обслуживаемыми и надежными.

Из IBM WebSphere Developer Technical Journal.

В каждой рубрике EJB Advocate приводится суть типичного диалога с реальными пользователями и разработчиками в процессе предоставления рекомендаций по решению какой-либо интересной проблемы. Идентификационные детали участников диалога не сообщаются, а новаторские или проприетарные архитектуры не применяются. Более подробная информация приведена в статье "Знакомство с EJB Advocate".

Проблема

Уважаемый EJB Advocate!

Я пишу Вам в надежде, что этот диалог поможет настроить продукт IBM® WebSphere® Application Server для решения проблемы, с которой мы столкнулись в текущей реализации EJB References.

Некоторые предварительные сведения: наша группа разработчиков приложений разбросана по всему миру и насчитывает более 1000 человек в четырех странах. Применяемая нами архитектура использует сессионный EJB-компонент с удаленным интерфейсом в качестве фасада к разнообразным сервисам, реализованным в POJO (plain old Java™ object). Каждый сервис может рассматриваться как выполняющий поток работ для одной или нескольких задач, которые сами реализованы в отдельных POJO для возможности повторного использования (данная задача может использоваться повторно в нескольких потоках работ и сервисах). Кроме того, задачи могут использовать другие сервисы (например, встречающиеся в сложных потоках работ).

Для того чтобы полностью использовать возможности повторного применения и квалификацию нашего отдела разработки, мы хотим, чтобы наши программисты не знали о существовании фасада сессии как контекста для их POJO-объектов. Проблема заключается в том, что каждый фасад сессии должен иметь в дескрипторе развертывания элемент EJB-REF для каждого фасада сессии, к которому обращается. В сущности, это требование означает необходимость знать обо всех сервисах, вызываемых задачами, вызываемыми реализацией данного сервиса. А поскольку мы не хотим нарушить инкапсуляцию задач, вызываемых данным сервисом, это становится чем-то большим, нежели простая головная боль при обслуживании, и требует от нас постоянного дублирования списков ссылок.

Будем рады любой помощи, особенно если Вы посоветуете инструментальную программу, которая может исследовать наш код и автоматически генерировать EJB-ссылки вместо нас.

Искренне ваш,
Cross with EJB References (Опутанный EJB-ссылками)

Погружение в детали реализации для выявления архитектурной несогласованности

У EJB Advocate самого заболела голова, когда он прочел фразу о "всех сервисах, вызываемых задачами, вызываемыми реализацией данного сервиса". Такая рекурсия указывает на несогласованность в способе реализации сервисов и задач, которые были разработаны раздельно и, возможно, разными людьми. Однако EJB Advocate хотел бы выяснить некоторые подробности:

Уважаемый Cross!

Ваша архитектура кажется очень похожей на некоторые другие, с которыми я сталкивался прежде, и в которых поведение потока работ обрабатывалось сессионными компонентами и вспомогательными классами. Решение Вашей проблемы, возможно, не требует понимающих код инструментальных программ, но прежде чем предложить что-либо конкретное, мне хотелось бы убедиться, что я правильно понимаю все детали. На рисунке 1 изображена общая архитектура, как я ее понял из Вашего описания.

Рисунок 1. Общая архитектура
Рисунок 1. Общая архитектура

Несколько вопросов (слева направо в приведенной выше архитектуре):

  1. Знает ли Client (который может быть задачей, как показано на диаграмме), что использует удаленный сессионный EJB-компонент, или эти детали скрыты за определенного типа POJO (аналогично компоненту Access)? Причина, по которой я задаю этот вопрос, состоит в том, что, как мне кажется, Вы пытаетесь полностью скрыть использование EJB-компонентов в архитектуре, и я хотел бы увидеть, насколько далеко вы продвинулись в этом отношении.
  2. Является ли POJO Task истинным подтипом Client, как я показал выше? То есть, я должен убедиться, что Ваш ответ на первый вопрос относится к реализации POJO Task. Если нет, я должен знать, как POJO Task будет обращаться к "под"-сервисам в реализациях его метода.
  3. Каков уровень модульности фасада сессии? Это единственный метод? Или несколько методов? Причина этого вопроса состоит в том, что я пытаюсь выяснить, как сервисы отображаются объекту Client, независимо от того, как они реализованы.
  4. Каков уровень модульности POJO Service? Соответствуют ли его методы один в один методам фасада сессии? Ответ прояснит мне принципы организации Ваших сервисов и объем действий по параллельной разработке, который мы можем ожидать.
  5. Как POJO Service обнаруживает POJO Task? Оператор new? Фабрика? Синглтон (singleton)? Ответ на этот вопрос будет важен для миграции существующего кода, если это потребуется.
  6. Каков уровень модульности POJO Task? Это один метод? Или несколько методов?
  7. Является ли POJO Task сохраняющим состояние (stateful) или нет (stateless)? Предложение, которое я сделаю, будет зависеть от того, следуете ли вы шаблону "команда", например:
    1. создать задачу (или получить ее из пула)
    2. установить свойства, представляющие входные данные
    3. выполнить ее
    4. получить свойства, представляющие выходные данные
    5. удалить ее (или поместить обратно в пул).
    См. диаграмму последовательности на рисунке 2.

Рисунок 2. Диаграмма последовательности для сохраняющего состояние шаблона "команда"
Рисунок 2. Диаграмма последовательности для сохраняющего состояние шаблона "команда"

Ваш EJB Advocate

Вот какой пришел ответ:

Уважаемый EJB Advocate!

Спасибо за немедленный ответ. Вот ответы на Ваши вопросы:

  1. Клиенты используют оператор new для создания POJO, который мы называем "бизнес-делегатом" ("Business Delegate" или BD), скрывающим детали получения Home и создания Session. Аналогично Session, BD генерируется из POJO Service. Вы в основном правы в том, что мы пытаемся полностью скрыть использование EJB-компонентов от наших программистов. Использование EJB-компонентов в первую очередь обязательно в нашей организации, но мы допустили использование сессий, чтобы получить управляемую контейнером дистанционность, защищенность и транзакциональность.
  2. Реализации методов POJO Task тоже используют BD, так же как и любой другой Client, как Вы и показали.
  3. Интерфейс Session имеет несколько методов, связанных каким-либо осмысленным способом.
  4. Методы POJO Service один в один соответствуют фасаду Session Bean.
  5. Методы POJO Service просто используют оператор new() для создания POJO Task. Идея заключается в том, чтобы методы POJO Service и Task были "чистыми" Java-методами и как можно более простыми. И, между прочим, в определенных обстоятельствах, метод POJO Service будет создавать BD для другого POJO Service напрямую. Нам нравится способ "замыкания" программой WebSphere ORB-вызова, если два фасада Session размещаются вместе.
  6. Может быть несколько методов public в POJO Task, но чаще всего не больше одного. Это могут быть какие-либо private-методы.
  7. Методы POJO Task не сохраняют состояния, как Вы показали в диаграмме последовательности. Но я бы хотел увидеть это различие в архитектуре, если бы мы использовали показанную Вами программную модель в командном стиле.

Надеюсь, что данные ответы помогут Вам предложить решение.

Искренне ваш,
Cross with EJB References (Опутанный EJB-ссылками)



В начало


Скромное предложение: используйте сессионные EJB-компоненты также и для задач

Ответы почти такие, которые и ожидал EJB Advocate, за исключением того, что задачи являются не сохраняющими состояния. Хорошо. В любом случае, по-видимому, проблема возникла из-за того, что задачи не трактуются как полноценные компоненты, которыми они являются (на ум приходит афоризм "если это ходит, крякает и выглядит как утка...").

Вот наша рекомендация:

Уважаемый Cross!

Спасибо за Ваши ответы, поскольку они предоставили мне достаточно информации, чтобы предложить решение. Ниже представлена модифицированная диаграмма классов, учитывающая сообщенную Вами дополнительную информацию и используемая для сравнения с диаграммой, которую я порекомендую ниже.

Рисунок 3. Скорректированная общая архитектура
Рисунок 3. Скорректированная общая архитектура

Практическое правило, которое я люблю применять, если код разрабатывается и тестируется отдельно, заключается в том, чтобы этот код пакетировался как компонент. Давайте на минутку сделаем вид, что Ваша команда разработчиков не противится использованию EJB-компонентов. В этом случае я порекомендовал бы, чтобы Services и Tasks были реализованы как сессионные компонента. Почему? Потому что основным преимуществом сессионных EJB-компонентов, за которыми присматривают Ваши разработчики, является удобство обслуживания и надежность.

Одним отличием, имеющимся, по-видимому, между Services и Tasks, является то, что Services доступны удаленно, а Tasks - локально. Поэтому я буду отображать и использовать интерфейс Remote для Services и интерфейс Local для Tasks, как показано на рисунке 4.

Рисунок 4. Предлагаемая общая архитектура с удаленными сервисами и локальными задачами
Рисунок 4. Предлагаемая общая архитектура с удаленными сервисами и локальными задачами

Если бы Tasks отображали сохраняющую состояние программную модель для сервисов (как я в начале и предполагал), они объявлялись бы как stateful вместо stateless в дескрипторе развертывания EJB. Накладные расходы на локальный сессионный EJB-компонент относительно не большие, поэтому производительность не должна быть проблемой, даже если он является сохраняющим состояние. (Отклонимся ненадолго от темы. Некоторые утверждают, что сохраняющие состояние сессионные компоненты никогда не должны использоваться. Однако мы никогда не говорим никогда. Мы рады порекомендовать их в данном случае, поскольку они развертываются локально для Service; следовательно, сохранение состояния происходит в контексте транзакции, начатой самым внешним сессионным компонентом, представляющим Service. Короче говоря, если Вы хотите использовать локальный EJB-компонент управления данными за фасадом сессии, желательно также использовать локальный сохраняющий состояние сессионный EJB-компонент за этим фасадом.) В любом случае, имеются преимущества, которые оправдывают накладные расходы, связанные с разработкой Tasks в виде сессионных EJB-компонентов, независимо от того, являются они сохраняющими состояние или нет.

Естественно, самое важное преимущество состоит в том, что данная архитектура решает Ваши проблемы повторного использования и EJB-REF. Программисты, создающие Services, могут использовать Tasks (и Services, в определенных обстоятельствах, как Вы описали). Программисты, создающие Tasks, могут использовать Services. В любом случае дескриптор развертывания для каждого сессионного компонента (Task или Service) просто содержит EJB-REF для сессионного компонента, который действительно использует. Инкапсуляция поддерживается, что является основой удобства обслуживания.

Еще одним преимуществом создания каждого объекта Task как EJB-компонента является то, что Вы можете выполнять модульное тестирование Tasks независимо от Services, которые могут их вызывать (сюда входит и тестирование EJB-REF, которые они используют). Все, что облегчает тестирование компонентов, хорошо для обеспечения надежности.

Также часто не замечаемым преимуществом явного основанного на EJB подхода является то, что Ваша бизнес-логика может воспользоваться EJB-контекстом для получения доступа к информации, например, о пользователе, сделавшем вызов, и о транзакции, активной в данный момент времени. Эта способность упрощает сигнатуры методов Service и Task (хотя я не спрашивал, но полагаю, что ID пользователей и другая информация, доступная в контексте сессии, явно передается в сигнатуры методов POJO Service и Task; мы можем оставить эту тему для отдельной дискуссии).

Но, даже учитывая все вышесказанное, я подозреваю, что Вы все равно не будете открывать возможность явного использования EJB-компонентов разработчикам. Компромиссом является генерирование "бизнес-делегата" и ассоциированных сессионных EJB-компонентов из POJO-объектов Task, как показано на рисунке 5.

Рисунок 5. Бизнес-делегат и ассоциированные EJB-компоненты для сервисов и задач
Рисунок 5. Сгенерируйте бизнес-делегат и ассоциированные EJB-компоненты для сервисов и задач

Код POJO Service необходимо будет изменить для создания Task Delegate вместо POJO Task. Но хорошая среда IDE упростит процесс миграции. И изменение того стоит, поскольку данный подход поможет сделать архитектуру намного более сервис-ориентированной и гибкой в отношении параметров развертывания.

Удачи в ваших будущих работах.

Ваш EJB Advocate



В начало


Заключение

В данном обсуждении мы рассмотрели применение сессионных EJB-компонентов - удаленных и локальных, сохраняющих и не сохраняющих состояния. Надуюсь, мы добавили удобство обслуживания и надежность в список преимуществ (в него уже входят распространение, защищенность и транзакции), которые проектировщики будут учитывать при выборе EJB-компонентов.

Практическим правилом, о котором нужно помнить, является то, что сервис-ориентированная архитектура требует функциональной декомпозиции - декомпозиция приводит к компонентам, которые, в конечном счете, нуждаются в поддержке, а компоненты в Java лучше всего реализуются сессионными EJB-компонентами (с или без вспомогательного класса, который делает сессионный EJB-компонент фасадом). Попытка спрятать использование EJB-компонентов - это одно (обычно приводит к некоторым оправданным накладным расходам), а попытка избежать использования компонентов - это другое (обычно приводит к возникновению проблем).

Что дальше...

В следующей статье мы исследуем детали того, как проектировать сигнатуры EJB-методов. Мы расширим использование информации EJB-контекста, а также сохраняющей состояние программной модели, представленной здесь, и покажем, как эта модель всегда может быть преобразована в не сохраняющую состояние, если Вы хотите чем-то поступиться.



Ресурсы



Об авторе

Джефф Хэмбрик (Geoff Hambrick) является ведущим консультантом IBM Software Services для группы обеспечения WebSphere (WebSphere Enablement Team). Он живет в Раунд Рок, Техас (недалеко от Остина). Общей задачей группы обеспечения является поддержка предпродажных процессов, которая осуществляется с помощью подробного технического инструктажа и кратковременных совещаний по проверке концепций. За свою работу по созданию и распространению передового опыта для разработки приложений J2EE на базе IBM WebSphere Application Server в марте 2004 года Джефф был удостоен звания инженера с отличием IBM (IBM Distinguished Engineer).




Выскажите мнение об этой странице


Пожалуйста, найдите минутку и заполните форму, чтобы повысить уровень сервиса.



ДаНетНе знаю
 


 


12345
 


В начало


IBM обладает всеми авторскими правами касательно информации, расположенной на developerWorks. Использование информации приведенной на этом ресурсе без явного письменного разрешения от IBM или первоначального автора запрещены. Если Вы желаете использовать информацию с developerWorks, пожалуйста воспользуйтесь регистрационной формой для того, чтобы связаться с нами запрос на использование материалов developerWorks Россия.

    IBM в России Конфиденциальность Контакты