2011-01-25 93 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更容易使用的事實外,您還可以自由更改底層(複雜)實現,而不會破壞客戶端代碼。