14

我想问在访问EJB Session Bean时使用Facade Pattern的原因是什么。在我的 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 中的某个地方,我必须这样persistUserSchool然后我必须这样做

someManagedBean.java

...
@EJB
private UserFacade userEJB;

@EJB
private SchoolFacade schoolEJB;

...

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

这是正确的做法吗?

4

3 回答 3

24

使用 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 中删除但未添加到另一个 Schoold .

于 2011-04-12T14:42:34.317 回答
7

是和不是。Facade 模式很有意义,但是每个域对象有一个单独的 face 是没有意义的。

您将希望根据域对象的功能组对外观进行分组。想象一个计费系统。它有账单、物品、客户、地址。因此,您可能会有一个用于账单处理(添加项目、设置客户、打印、标记为已付款)的外观和用于创建和更新用户、与地址关联等的不同外观。

于 2011-04-12T14:32:16.500 回答
1

我认为您应该有一个 AbstractFacade 用于典型的 CRUD 操作,如您所见,以及许多 SpecificFacade 用于操作给定实体。因此,您不能多次重新实现相同的基本逻辑......而只专注于与实体关联的更复杂的逻辑(事务)。

于 2015-07-11T15:36:04.380 回答