2011-01-25 90 views
13

我并不真正了解门面的要点。Java EE中的Facade有什么意义?

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 void edit(T entity) { 
     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() { 
     CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery(); 
     cq.select(cq.from(entityClass)); 
     return getEntityManager().createQuery(cq).getResultList(); 
    } 

    public List<T> findRange(int[] range) { 
     CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery(); 
     cq.select(cq.from(entityClass)); 
     Query q = getEntityManager().createQuery(cq); 
     q.setMaxResults(range[1] - range[0]); 
     q.setFirstResult(range[0]); 
     return q.getResultList(); 
    } 

    public int count() { 
     CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery(); 
     Root<T> rt = cq.from(entityClass); 
     cq.select(getEntityManager().getCriteriaBuilder().count(rt)); 
     Query q = getEntityManager().createQuery(cq); 
     return ((Long) q.getSingleResult()).intValue(); 
    } 
} 

如果我有这个代码,然后我有这样的EJB。

@Stateless 
public class WrapSpecFacade extends AbstractFacade<WrapSpec> { 
    @PersistenceContext 
    private EntityManager em; 

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

    public WrapSpecFacade() { 
     super(WrapSpec.class); 
    } 

} 

这是什么意思?为什么称这是一个门面?对我来说,这只是一个抽象类,它将类似的功能进行分组。谢谢。

回答

16

门面是一种设计模式。模式是软件模式,它是一组规则,用于组织代码并为其提供特定的结构。有些目标可以通过使用模式来达成。 设计应用程序时使用设计模式。

Facade模式允许程序员为对象创建一个简单的接口来使用其他对象。 考虑使用一组非常复杂的类,所有类都实现它们自己的接口。 那么,你想提供一个接口,只公开你所拥有的许多功能。通过这样做,您可以实现代码简单性,灵活性,集成性和松散耦合。

在您的示例中,门面用于管理多个参与者之间的耦合。这是一个设计问题。当你有很多组件交互在一起时,它们越紧密地维护它们(我的意思是代码维护)。门面允许你达到松耦合,这是程序员应该总是试图达到的目标。

考虑以下几点:

public class MyClass1 implements Interface1 { 
    public void call1() {} 
    public call call2() {} 
} 

public class MyClass2 implements Interface2 { 
    public void call3() {} 
    public void call4() {} 
} 

public class MyClass { 
    private MyClass1 a; 
    private MyClass2 b; 
    //calling methods call1 call2 call3 and call4 in other methods of this class 
    ... 
    ... 
} 

如果你不得不改变位于使用CALL1或CALL2 ......通过不改变接口的类的业务逻辑,你就不会需要改变所有这些类,而只是前两个类的其中一个接口方法所使用的方法内部的类。

Facade让您改进此机制。

我很抱歉,但我意识到它看起来并不那么美妙。设计模式在软件行业中被大量使用,在处理大型项目时它们可能非常有用。 您可能会指出,您的项目并不那么庞大,这可能是事实,但Java EE旨在帮助业务和企业级应用程序编程。这就是为什么有时默认使用外观模式(一些IDE也使用它)。

7

通常,这种模式被用来隐藏它提供接口的底层类的实现,或者简化可能很复杂的底层实现。

一个外观可能会提供一个简单的界面到外部世界,但引擎盖下的事情就像创建其他类的实例,管理事务,处理文件或TCP/IP连接 - 您可以屏蔽的所有东西简化的界面。

6

在您的特定情况下,这不是真正的Facade。你在那段代码中基本上是一个DAO(数据访问对象)。

DAO可以看作是数据库操作的Facade,但这不是它的主要目的。它主要是为了隐藏DB内部。在您的示例中,如果您将底层存储系统切换为XML文件或HBase等键值存储,则仍然可以使用该“Facade”中定义的方法,并且客户端代码中不需要进行更改。

A(传统)门面处理复杂的设计,需要从客户隐藏。除了暴露一个复杂的API和复杂的流程(从这个服务中获取它,将它传递给这个转换器,获得结果并使用它进行验证,然后将其发送给这个其他服务),你只需将所有这些封装在Facade中,向客户展示一个简单的方法。这样,除了您的API更容易使用的事实外,您还可以自由更改底层(复杂)实现,而不会破坏客户端代码。