28 July 2005

如果你曾經看過 Spring 的書或是 manual,你會發現大家不約而同的,都替 DAO 做 interface,然後再 extends DAOSupport implement DAO interface:

public interface AccountDAO {}

public class HibernateAccountDAO 
         extends HibernateDAOSupport implement AccountDAO {}

書上都是寫說希望 DAO layer 能跟 ORM decouple.... 所以要用interface 隔開.... 但個人比較 prefer下面較直接的做法:

public class AccountDAO {
    private HibernateTemplate hibernateTemplate ;
    public void setHibernateTemplate(HibernateTemplate ht) {...;}
}

That's all ! 這樣簡單多啦。雖然interface沒了,不過要做 mockDAO 一點也不難,可以用 EasyMock 的 extension:

MockControl control = MockClassControl.createControl(AccountDAO.class);
AccountDAO mockAccountDAO = (AccountDAO) control.getMock() ;

毫無困難 ^_^

回頭來討論一下:到底 DAO layer 和 ORM decouple 重不重要?個人覺得在實務上一點都不重要!

  • 抽換 ORM framework 機會很少。 試想你有遇過要將 ORM 抽換掉的需求嗎?像是從 Hibernate 轉移到 JDO/iBatik/toplink/EJB (或是反過來)這樣...
  • ORM framework 特性不一。ORM 雖然可以封在 DAO layer 裡,但 ORM 都有各自的特性和能力,DAO 的上一層 domain layer / service layer 多多少少要牽就 ORM 的能力來設計... 所以用 interface 也不能保證能將全部 DAO layer 隔開....
  • 一旦用了 xxx framework,規模一大起來 (>100 class),轉換 framework 都需要秏費非常非常多的資源。如果最後真的決定要換,通常都換的很徹底,比方說除了 DAO layer 重寫外,也順便翻新以前設計錯誤的地方... 如此改來改去的,interface 的好處自然就更少了...
  • Decouple 可以防止 vendor locking... 這一點 Hibernate 已經將 Database vendor 隔開了,所以沒有綁 vendor 的問題,不需要再花工夫... 那綁 Hibernate 有什麼問題?lock 誰?個人實在是想不出來....

Spring 的作者群多半都是由 framework 的角度切入,而 Spring framework 的有一部份的精神在於 non-invasive、decoupling 上。自然他們會視 decoupling ORM 為重要的需求,所以書上的寫法都是那個樣... 就個人來看,在實務上這是不必要的。


回響

可以用 Tag <I>、<B>,程式碼請用 <PRE>