2011-08-30 79 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的反模式的动机很简单 不够 - 开发商希望的方式来定义更紧凑的类型标识符 ,尤其是仿制药使类型标识符更详细 。问题在于,这种习惯用法在使用它的代码和代码的客户端之间创建了紧密耦合,阻止了重用。您可能不喜欢泛型类型标识符的详细程度,但这不是解决问题的方法。

相关问题