Entity Framework - 一個組織階層的ORM範例(下)

Entity Framework - 一個組織階層的ORM範例(下)

前篇文章介紹了如何架構一個組織階層的設計,並透過EF實現OO的做法.

而最後的查詢確相當不直覺,因為使用端必須了解底層資料結構查詢的方式,這破壞了OO三大原則中的封裝.

 

底下開始介紹如何封裝這部分.

以往最常看到的方式就是將某些方法直接封裝在Domain物件中.

譬如在Customer物件增加新增刪除的功能

    public class Customer

    {

        public int Id { get; set; }

        public string CustomerName { get; set; }

 

        public void AddCustomer(string customerName)

        {

            ...

        }

 

        public void DeleteCustomer(int customerId)

        {

            ...

        }

    }

上述做法常在一些書籍或網站中看到,而這種做法不能說不對,而是不好.因為這破壞了OO設計中的一些準則,物件的責任除了描述物件本身外,還產生與物件無關的行為(Add與Delete),這會產生 高耦合度與低凝聚力 的問題.

所以最好的方式應該將AddCustomer與DeleteCustomer切割出來.

但問題是該放到哪?

如果使用EF有人可能會直接將這些方法放置到實作ObjectContext物件中.如同EF精靈產生的ObjectContext物件包含了很多如Customers,Employees等ObjectQuery物件.

這麼作不能說是不對但也有缺點 1.如果物件很多,相對的ObjectContext物件會有落落長的如AddXXX等函式 2.如果出現與DB無關的一些方法放置在ObjectContext就顯得奇怪,但若另外放置到其他地方又會導致使用端使用時必須了解方法在哪.

而這問題的解決方案有個比較好的做法就是透過 repository pattern(責任樣式),而目前EF4也建議使用repository pattern來處理這類問題.

因repository pattern搭配EF作法每個人想法不同,但最終理念是相同的,所以提供兩篇文章做參考,文中就不詳述(其實是懶得打…)

兩篇文章

http://www.codeproject.com/KB/database/ImplRepositoryPatternEF.aspx

http://blog.keithpatton.com/2009/05/30/Entity+Framework+POCO+Repository+Using+Visual+Studio+2010+Net+40+Beta+1.aspx

 

而我本身也有自己的想法做了相關的repository  class,與上面不同的是我多了搭配Ioc樣式(參考說明:http://dev.csdn.net/develop/article/24/24397.shtm)為了方便事後的Unit Test.

所以首篇文章的查詢最終在使用端就會封裝為下面程式的使用方式

            using (ICustomerRepository repository = ObjectRepositoryFactory.GetRepository<ICustomerRepository>())

            {

                Customer cus = repository.GetCustomerById(1);

                List<Customer> list = repository.CreateQuery().Where(c => c.Parent.Id == 1).ToList();

            }

透過repository pattern將相關方法封裝在類別中,使用端就不需了解細節的處理.

 

當然EF配合repository pattern還有很多細節,下次再介紹了.

 

這兩篇文章省略掉了很多細節,將焦點聚集在如何透過EF與OO解決一些問題, 並未太深入一些技術上的介紹,未來將會再慢慢補充這些資料,