2012-03-19 47 views
1

我POCO的結構基本上是這樣的:什麼時候POCO類的擴展方法過度殺傷?

Person其中有:AddressesPhonesCaseNotesNoticeOfActions

我開始書面方式一個PersonExtension類,我發現非常有用有,比方說,下面的例子方法:

public static Person GetPersonsPhones(this Person person, string userID) 
{ 
    using (var context = ConnectDataContext.Create()) 
    { 
     var pPhones = 
      context.tblPhones.Where(phones => phones.PersonID == person.PersonID).Select(
       phones => 
       new Phone() 
        { 
         PhoneID = phones.PhoneID, 
         PhoneType = 
          new PhoneType 
           { 
            PhoneTypeID = phones.tblAdminPhoneType.PhoneTypeID, 
            TypeDescription = phones.tblAdminPhoneType.PhoneTypeDesc 
           }, 
         PhoneNumber = phones.PhoneNumber, 
         Extension = phones.Extension 
        }); 
     person.Phones = pPhones.ToList<Phone>(); 
     return person; 
    } 
} 

現在我也有類似的擴展方法是人獲得地址集合。我想知道的是,如果有一點,這是有害的。由於我的環境的性質,幾乎所有的東西都適合Person,has-a的方式。

沒問題,或者有什麼不好的,我會從中遇到?我是否會因此而招致更多開銷?

替代似乎是簡單地傳遞Person.ID,因爲這是我需要從DB的手機,然後將其添加到我的Person對象,但似乎,我反正是同一件事。


我認爲這裏有一個通信故障這是最有可能是我的錯,因爲我不經常使用的東西的話語權。

在我的數據庫中有tblPerson和tblPhone。我有一個叫Person的班級和一個叫Phone的班級。我的Person類有一個屬性IList<Phone>Phones
有問題的擴展方法是針對我的基類的子屬性的CRUD方法。
Person.GetPhones()填充IList<Phone>Phones屬性Person對象。 Person.SavePhones()Save對該Person對象的數據庫的Phones的任何更改。

我並不認爲我在做什麼是正確的(我懷疑這是... :()只是想確保每個人都明白我是問。
另外,我使用LinqToSQL爲DB訪問。

+1

這種事真的應該在一個存儲庫中,而不是在你的實體類IMO中。 – tvanfosson 2012-03-19 18:45:57

+1

當我得到**表決**時,我很欣賞一些關於我的問題出了什麼問題的指示,以便我可以在將來學會正確地做到這一點。 Just say' – 2012-03-19 19:08:06

回答

3

我認爲主要的缺點會傾向於代碼的組織。是不是OOP的點,要盡力保持相關的代碼放在一起?

我很好奇,你爲什麼在這裏使用的擴展方法如果Person是一個實體對象,我會創建一個擴展實體類的分類類,似乎是一個更好的組織離開這裏給我。

+0

雖然與Person.Phones = BLL.GetPhones(Person)相比,寫'Person.GetPhones()'的功能相當方便,但我可以看到您關於代碼組織的觀點。Person只是我簡單的POCO或可能的Domain Object正如下面的人指出的那樣。 'tblPerson'將是LinqToSQL爲表生成的實體表示。 – 2012-03-19 19:04:51

0

如果是你的班級,那麼你應該爲班級編寫真正的方法。擴展方法對於向不能更改的類添加功能非常有用,例如,來自沒有源代碼的庫的類,您不能從中派生。

+1

即使您可以更改界面,擴展方法也可用於向界面添加功能。如果新功能可以完全按照現有的接口方法來實現,那麼它應該是一種擴展方法。 – Timwi 2012-03-19 18:50:54

4

你這裏的人應該是一個完全成熟的domain object,而不是一個POCO。該人應該tell some thing their phone numbers,該人不應該負責去數據庫並將其提取出來!後者適用於是否選擇擴展方法。

但是,關於您的問題,我將擴展方法看作擴展第三方代碼的某些功能的方式。例如,您可以在字符串上執行ToUpper()。這將是很好的擴展這個做標題案例。我們在這裏擴展行爲。我們正在「添加」第三方代碼,但沒有提供源代碼,因爲替代方法是引入一個包裝字符串的新對象。這裏的擴展方法只是真正的語法糖。

如果你擁有代碼,那麼擴展方法是毫無意義的,因爲你可以使該方法成爲正在討論的類的完全方法。我這樣說的原因是,通過適當的方法,您可以訪問正在擴展的類的私有字段,因此使用擴展方法僅限於公開可見性,就像正常的靜態方法一樣。

+1

擴展方法還有另外一點:如果你想爲接口添加功能,就像LINQ一樣。 – 2012-03-19 18:54:40

+0

順便說一句,有一個TextInfo.ToTitleCase()方法可以做到這一點,雖然在字符串上添加一個擴展方法來調用它也不錯。 http://msdn.microsoft.com/en-us/library/system.globalization.textinfo.totitlecase(v=vs.100).aspx – 2012-03-19 18:56:08

+0

@JamesMichaelHare這只是我頭頂的一個例子,但是,它應該在大多數使用情況下是真正的字符串。 – Finglas 2012-03-19 18:56:56

2

如果您使用的是帶有的EntityFramework代碼優先模型的POCO類,你應該能夠寫這樣您的POCO類(僅包括手機,現在,只是爲了演示):

class Person 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 

    public virtual ICollection<Phone> Phones { get; set; } 
} 

class Phone 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 
    public long PersonId { get; set; } 

    public virtual Person Person { get; set; } 
} 

現在你可以直接訪問myPerson.Phones,並且不需要您的擴展方法。

+0

我相信這是我已經有,雖然我使用LinqToSQL非實體框架。我的擴展方法是用來自數據庫的數據填充Phones屬性。也許我錯過了一些東西。 – 2012-03-19 19:01:15

+0

@RefractedPaladin:那麼,是從實體設計器的自動生成的代碼中聲明的屬性?在這種情況下,它*應該*沒有擴展方法。還是你自己宣佈?在這種情況下,您可以直接實現該屬性而不是使用擴展方法。即使你需要它是一個單獨的方法出於任何原因,它仍然不需要是一個*擴展*方法 - 我相信實體設計器聲明類爲[partial classes](http://msdn.microsoft .com/en-us/library/wa80x488%28v = vs.80%29.aspx)所以只需要聲明另一部分的方法。 – Timwi 2012-03-19 19:13:06

相關問題