Шаблон составного объекта - Composite entity pattern
Составная сущность это Java EE Шаблон проектирования программного обеспечения и он используется для моделирования, представления и управления набором взаимосвязанных постоянных объектов, а не для представления их в виде отдельных мелкозернистых объектных компонентов, а также составной объектный компонент, представляющий граф объектов.[1]
Структура
Существует ряд стратегий для реализации шаблона составной сущности. Этот шаблон в основном состоит из составного объекта, крупнозернистого объекта и зависимых объектов.[1]
Компонент составного объекта
Составная сущность - это объектный компонент общего назначения, который может быть крупным объектом или может содержать ссылку на крупнозернистый объект.[1]
Крупнозернистый объект
Крупнозернистый объект - это объект со своим собственным жизненным циклом, который управляет своими собственными отношениями с другими объектами. Это может быть объект, содержащийся в составном объекте, или сам составной объект может быть объектом общего назначения, который содержит зависимые объекты.[1]
Зависимые объекты
Это объект, который может содержать другие зависимые объекты (в составном объекте может быть дерево объектов), который зависит от объекта общего назначения и жизненный цикл которого управляется объектом общего назначения.[1]
Последствия
Согласно описанию шаблона Oracle, последствия включают устранение взаимосвязей между сущностями, улучшение управляемости за счет сокращения объектных компонентов, повышение производительности сети, уменьшение зависимости схемы базы данных, увеличение детализации объекта, облегчение создания составного объекта передачи и накладные расходы на многоуровневые зависимые графы объектов. .[1]
Недостатки
Фатальный недостаток - требование постоянных файлов, управляемых компонентами (BMP). фасоль. Это требует дополнительных усилий для разработчиков и создает следующие проблемы:
- материализация всех данных в крупномасштабном объекте всякий раз, когда к нему обращаются, неприемлемо дорого
- В Ява реализация метода ejbStore () должна быть достаточно продуманной, чтобы избежать выпуска всех обновлений, необходимых для сохранения всего состояния объекта, если только данные не изменились во всех постоянных объектах.
Шаблон составной сущности может быть реализован только с использованием BMP или путем добавления дополнительной логики сохраняемости, закодированной вручную, к сохраняемости, управляемой контейнером (CMP) бобы. Оба эти подхода снижают ремонтопригодность.[2]
Образец кода
Пример кода для приложения Professional Service Automation (PSA), в котором объект ресурса реализован через шаблон составной сущности, может выглядеть следующим образом (сущность реализует объект общего назначения):
упаковка corepatterns.apps.psa.ejb;импорт corepatterns.apps.psa.core. *;импорт corepatterns.apps.psa.dao. *;импорт java.sql. *;импорт javax.sql. *;импорт java.util. *;импорт javax.ejb. *;импорт javax.naming. *;общественный учебный класс ResourceEntity орудия EntityBean { общественный Нить employeeId; общественный Нить фамилия; общественный Нить имя; общественный Нить DepartmentId; общественный Нить PracticeGroup; общественный Нить заглавие; общественный Нить оценка; общественный Нить электронное письмо; общественный Нить Телефон; общественный Нить клетка; общественный Нить пейджер; общественный Нить managerId; // Коллекция объектов, зависящих от BlockOutTime общественный Коллекция blockoutTimes; // Коллекция объектов, зависящих от SkillSet общественный Коллекция набор умений; ... частный EntityContext контекст;// Реализация методов Entity Beanобщественный Нить ejbCreate(ResourceTO ресурс) бросает CreateException { пытаться { это.employeeId = ресурс.employeeId; setResourceData(ресурс); getResourceDAO().Создайте(ресурс); } ловить(Исключение бывший) { бросать новый EJBException("Причина:" + ...); } возвращаться это.employeeId;} общественный Нить ejbFindByPrimaryKey(Нить первичный ключ) бросает FinderException { логический результат; пытаться { ResourceDAO resourceDAO = getResourceDAO(); результат = resourceDAO.selectByPrimaryKey(первичный ключ); } ловить(Исключение бывший) { бросать новый EJBException("Причина:" + ...); } если (результат) { возвращаться первичный ключ; } еще { бросать новый ObjectNotFoundException(...); } } общественный пустота ejbRemove() { пытаться { // Удаляем зависимые объекты если (это.набор умений != ноль) { SkillSetDAO skillSetDAO = getSkillSetDAO(); skillSetDAO.setResourceID(employeeId); skillSetDAO.удалить все(); набор умений = ноль; } если (это.blockoutTime != ноль) { BlockOutTimeDAO blockouttimeDAO = getBlockOutTimeDAO(); blockouttimeDAO.setResourceID(employeeId); blockouttimeDAO.удалить все(); blockOutTimes = ноль; } // Удаляем ресурс из постоянного хранилища ResourceDAO resourceDAO = новый ResourceDAO(employeeId); resourceDAO.Удалить(); } ловить(ResourceException бывший) { бросать новый EJBException("Причина:"+...); } ловить(BlockOutTimeException бывший) { бросать новый EJBException("Причина:"+...); } ловить(Исключение исключение) { ... } } общественный пустота setEntityContext(EntityContext контекст) { это.контекст = контекст; } общественный пустота unsetEntityContext() { контекст = ноль; } общественный пустота ejbActivate() { employeeId = (Нить)контекст.getPrimaryKey(); } общественный пустота ejbPassivate() { employeeId = ноль; } общественный пустота ejbLoad() { пытаться { // загружаем информацию о ресурсе из ResourceDAO resourceDAO = getResourceDAO(); setResourceData((ResourceTO) resourceDAO.нагрузка(employeeId)); // При необходимости загружаем другие зависимые объекты ... } ловить(Исключение бывший) { бросать новый EJBException("Причина:" + ...); } } общественный пустота ejbStore() { пытаться { // Сохраняем информацию о ресурсах getResourceDAO().Обновить(getResourceData()); // Сохраняем зависимые объекты по мере необходимости ... } ловить(SkillSetException бывший) { бросать новый EJBException("Причина:" + ...); } ловить(BlockOutTimeException бывший) { бросать новый EJBException("Причина:" + ...); } ... } общественный пустота ejbPostCreate(ResourceTO ресурс) { } // Метод для получения объекта передачи ресурсов общественный ResourceTO getResourceTO() { // создаем новый объект передачи ресурсов ResourceTO ресурс = новый ResourceTO(employeeId); // копируем все значения ресурс.фамилия = фамилия; ресурс.имя = имя; ресурс.DepartmentId = DepartmentId; ... возвращаться ресурс; } общественный пустота setResourceData(ResourceTO ресурс) { // копируем значения из объекта передачи в объектный компонент employeeId = ресурс.employeeId; фамилия = ресурс.фамилия; ... } // Метод получения зависимых объектов передачи общественный Коллекция getSkillSetsData() { // Если набор навыков не загружен, сначала загрузите его. // См. Реализацию стратегии Lazy Load. возвращаться набор умений; } ... // другие методы получения и установки по мере необходимости ... // Бизнес-методы Entity Bean общественный пустота addBlockOutTimes(Коллекция больше) бросает BlockOutTimeException { // Примечание: moreBOTs - это набор // Объекты BlockOutTimeTO пытаться { Итератор больше = больше.итератор(); пока (больше.hasNext()) { BlockOutTimeTO botTO = (BlockOutTimeTO) больше.следующий(); если (! (blockOutTimeExists(botTO))) { // добавляем BlockOutTimeTO в коллекцию botTO.setNew(); blockOutTime.Добавить(botTO); } еще { // BlockOutTimeTO уже существует, добавить нельзя бросать новый BlockOutTimeException(...); } } } ловить(Исключение исключение) { бросать новый EJBException(...); } } общественный пустота addSkillSet(Коллекция больше навыков) бросает SkillSetException { // аналогично реализации addBlockOutTime () ... } ... общественный пустота updateBlockOutTime(Коллекция updBOTs) бросает BlockOutTimeException { пытаться { Итератор ботИтер = blockOutTimes.итератор(); Итератор обновление = updBOTs.итератор(); пока (обновление.hasNext()) { BlockOutTimeTO botTO = (BlockOutTimeTO) обновление.следующий(); пока (ботИтер.hasNext()) { BlockOutTimeTO существующийBOT = (BlockOutTimeTO) ботИтер.следующий(); // сравниваем ключевые значения, чтобы найти BlockOutTime если (существующийBOT.равно(botTO)) { // Найден BlockOutTime в коллекции // заменяем старый BlockOutTimeTO на новый botTO.setDirty(); // изменен старый иждивенец botTO.сброситьновый(); // не новый иждивенец существующийBOT = botTO; } } } } ловить (Исключение отлично) { бросать новый EJBException(...); } } общественный пустота updateSkillSet(Коллекция updSkills) бросает CommitmentException { // аналогично updateBlockOutTime ... ... } ...}