2011-08-30 77 views
6

我見過一些人建議你應該封裝泛型類型有一類更接近你的域名,例如史蒂夫和NAT在Growing Object-Oriented Software, Guided by Tests建議:什麼時候應該封裝泛型類型?

我們的經驗法則是,我們嘗試限制通過泛型類型傳遞[...]。特別是當應用於集合時,我們將其視爲重複的形式。這暗示有一個領域概念應該被提取到一個類型中。

在一般情況下,當它是一個好主意,做這樣的事情..

class PersonList : List<Person> 

..而不是僅僅使用List<Person>直接?

回答

1

因爲離開類型參數照樣不是真的幹。考慮這個類:

class Muffin { 
    List<string> _peopleWhoLikeMuffins = new List<string>(); 

    public Muffin(List<string> peopleWhoLikeMuffins) { 
     _peopleWhoLikeMuffins = peopleWhoLikeMuffins); 
    } 

    public void AddMuffinLiker(string p) { 
     _peopleWhoLikeMuffins.Add(p); 
    } 
} 

這是真的很短,只包含基本的功能,但我不得不使用string - genertic類型參數 - 四倍。它將永遠是一樣的。如果我決定稍後改變這種類型,我將不得不更換所有四種產品。

在現實世界的場景中,我們正在談論數百個而不是4個。因此,總是封裝它並不是一件容易的事情,但它絕對值得考慮。

現在,我的例子不是很好(不僅僅是因爲愚蠢的名字),但是你明白了 - 你會有很多字段和變量的聲明和實例化,每次你必須傳遞一個類型參數,該參數在整個代碼庫中始終保持不變,除非其他類也是通用的。

這樣做的另一個好處是,如果您需要向集合中添加一些額外的狀態/行爲,那麼您的工作量會少得多。

所有人都說,我自己並不經常使用這種抽象。

+3

在您給出的例子中,將Muffin泛化爲泛型(並將其與字符串一起使用)比對列表進行硬編碼更有意義,所以我不認爲它是有利於創建特定類型。 – sinelaw

+0

@sinelaw:是的,我在編輯中指出這個例子不太好,可能也應該是通用的 – Dyppl

2

我不同意這種理念。 List<Person>是一個類似於PersonList的類型。人員列表的域概念也被封裝在其中。如果你問我,最好儘可能使用泛型,除非使用它們限制你(見下文)或使代碼難以理解。例如,如果你甚至注意到它正在做一些普通的事情,那麼在PersonList上運行的函數將比在List<Person>上運行的函數更難以概括。

也就是說,特別是在Java中,泛型有一個限制,使得它們的吸引力大大降低。由於類型擦除,當涉及靜態方法/類型的成員時,不能充分利用泛型,並且您可能需要提取一種非泛型的特定類型,以便能夠將其用於某些事情。底線是,在Java中,您需要在許多情況下提取特定類型,如果這樣可以保持類型安全的話。

3

您在找什麼是用於Java或C#的typedef運算符。

不幸的是,子類化方法不是typedef的好替代品。

以下文章"Java theory and practice: The pseudo-typedef antipattern"解釋了爲什麼要詳細說明。

我會複製文章逐字結論這裏:

爲僞typedef的反模式的動機很簡單 不夠 - 開發商希望的方式來定義更緊湊的類型標識符 ,尤其是仿製藥使類型標識符更詳細 。問題在於,這種習慣用法在使用它的代碼和代碼的客戶端之間創建了緊密耦合,阻止了重用。您可能不喜歡泛型類型標識符的詳細程度,但這不是解決問題的方法。

相關問題