Зачем использовать шаблон Facade для сессионного компонента EJB? - PullRequest
14 голосов
/ 12 апреля 2011

Я хочу спросить, с чем связано использование Facade Pattern при доступе к EJB Session Bean.В моем Netbeans 6.9.1, если я сделаю New> Sessions Bean for Entity Classes и, скажем, выберу User сущность, тогда Netbeans сгенерирует этот код

AbstractFacade.java
public abstract class AbstractFacade<T> {
    private Class<T> entityClass;

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        getEntityManager().persist(entity);
    }

    public T edit(T entity) {
        return getEntityManager().merge(entity);
    }

    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

    public List<T> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }

    public List<T> findRange(int[] range) {
        ...
    }

    public int count() {
        ...
    }

И

UserFacade.java    

package com.bridgeye.ejb;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class UserFacade extends AbstractFacade<User> {
    @PersistenceContext(unitName = "Bridgeye2-ejbPU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public UserFacade() {
        super(User.class);
    }        
}

Я хочу спросить, в чем выгода от этого.Если бы у меня было 10 сущностей, то Netbeans сгенерировал бы 10 классов Facade плюс AbstractFacade.Это кажется излишним для меня.Скажем, где-то внутри моего управляемого боба мне нужно persist a User и School, тогда я должен сделать это

someManagedBean.java

...
@EJB
private UserFacade userEJB;

@EJB
private SchoolFacade schoolEJB;

...

public void someMethod(User user, School school){
    ...
    userEJB.create(user);
    schoolEJB.create(school);    
}

Это правильные вещи, которые нужно сделать?

Ответы [ 3 ]

22 голосов
/ 12 апреля 2011

Смысл использования EJB вообще заключается в том, что они предоставляют такие функции, как декларативные транзакции и безопасность через аннотации (или конфигурации XML). Если вы не используете эти функции, бессмысленно иметь EJB.

Кроме того, этот автоматически сгенерированный код фасада является отправной точкой (и плохой). EJB-компоненты должны формировать API домена, а не оболочку для всех отдельных операций CRUD. Они должны содержать только те операции, которые вы на самом деле хотите выполнить в модели вашего домена, и многие из них должны охватывать несколько операций CRUD, которые необходимо выполнить в рамках транзакции. Например:

@TransactionAttribute
public void transferUser(User u, School from, School to){
    from.getUsers().remove(u);
    to.getUsers().add(u);
    u.setSchool(to);
    getEntityManager().merge(from);
    getEntityManager().merge(to);
    getEntityManager().merge(u);
}

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

7 голосов
/ 12 апреля 2011

Да и нет. Шаблон «Фасад» имеет большой смысл, но не имеет смысла иметь отдельный фасад для каждого предметного объекта.

Вы хотите сгруппировать фасады по группам функциональности доменных объектов. Представьте себе биллинговую систему. Он имеет счета, предметы, клиента, адреса. Так что, возможно, вам понадобится Фасад для обработки счетов (добавление товаров, настройка клиента, печать, маркировка как платная) и другой фасад для создания и обновления пользователей, ассоциирования с адресами и т. Д.

1 голос
/ 11 июля 2015

Я думаю, у вас должен быть один AbstractFacade для типичных операций CRUD, как вы можете видеть, и множество SpecificFacade для манипулирования данным объектом. Таким образом, вы не можете переопределить одну и ту же базовую логику много раз только одним ... и сосредоточиться только на более сложной логике (транзакциях), связанной с сущностями.

...