Design Pattern — Data Access Object

DAO(Data Access Object) 應該是最基礎且最廣泛運用的一個設計模式了。其適用的情境為:

  • 程式需要利用別的媒介來儲存或取得資料
  • 程式需要能移植到其它儲存媒介
  • 各個儲存媒介之間使用的存取方式不同
  • 希望程式不會受到儲存媒介的變換而修改

DAO 通常看到的範例都會與另外一個物件搭配使用,稱之為 Data Transfer Object 。但是這兩者之間並不一定要綁在一起用。DAO 的重點在提供一個統一的資料存取方式,而回傳的資料可以用 DTO 表示,但也可以用其它方式(例如陣列)來實作。這邊以一個會員系統為例,如何以 DAO 模式來提供會員相關資料的存取。

首先需要設計一個 Interface 來提供資料的存取,這邊為了簡化程式數量,還是按照常見作法搭配 DTO 來使用:

有了這個 Interface 之後,我們就可以實作兩種 DAO 分別對應到記憶體與資料庫這兩種不同的儲存媒介:

因為偷懶的關係所以這兩個 DAO 長的根本一模一樣。但是實際應用的時候 MemoryUserDAO 應該只會帶有一些陣列操作之類的程式碼,而 MySQLUserDAO 裡面可能會有 PDO 及 SQL 語法,或是利用 ORM 來存取資料。

使用的時候我們就可以不用管 DAO 實際對應的媒介,只需要呼叫其界面提供的方法就可以了:

另外,當需要支援更多種類的儲存媒介,你可以很容易的實作更多的 DAO 來處理。而且完全不用修改現有的程式碼。這同時也提供了程式良好的可測性,我們只需要實作一個 DAO 來控制回傳的資料,就能測試各種資料組合的單元測試了。

總結一下優點:

  • 將特定媒介的 API 使用方式隔離在 DAO 內,易於維護
  • 易於新增或抽換儲存媒介
  • 降低程式的複雜度
  • 提昇可測性

參考資料:
http://www.oracle.com/technetwork/java/dataaccessobject-138824.html
http://www.adam-bien.com/roller/abien/entry/value_object_vs_data_transfer
http://martinfowler.com/eaaCatalog/dataTransferObject.html

發佈留言