Зачем использовать шаблон Facade для сеанса EJB bean

Я хочу спросить, в чем причина использования шаблона фасада при доступе к сессии EJB 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. Кажется, это слишком много для меня. Скажем, где-то внутри моего управляемого bean, я должен 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);    
}

Правильно ли это делать?

Ответы

Ответ 1

Точка использования 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, но не добавляется к другой.

Ответ 2

Да и нет. Шаблон Facade имеет большой смысл, но наличие отдельного аспекта для объекта домена не имеет смысла.

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

Ответ 3

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