2011-05-15 37 views
5

我想知道在严格OOP方面向内置类型(如字符串或整数或更复杂的对象(在我的情况下是BitSet类))中添加功能的最佳方式是什么。向内置类型添加功能的最佳方式

更具体 - 我有两个场景:

  1. 添加MD5散列方法的字符串对象
  2. 添加转换方法(如fromByteArray()或toInteger())的位集合类。

现在我想知道实现这个的最佳实践是什么。

我可以例如创建一个从BitSet扩展的新类“BitSetEx”并添加我的方法。但我不喜欢这个想法,因为这个新类需要描述名称,而“BitSetWithConversionMethods”听起来真的很愚蠢。

现在我可以写一个只包含静态方法的类来完成转换。

那么我有很多想法,但我不想知道什么是OOP意义上的“最佳”。

所以有人可以回答我这个问题吗?

回答

3

有几种方法在这里:

首先,你能想出了extends BitSet类一个更好的名字。不,BitsetWithConversionMethods不是一个好名字,但也许像ConvertibleBitSet是。这是否表达了课堂的意图和用法?如果是这样,这是一个好名字。同样,您可能有HashableString(请注意,您不能延长String,正如Anthony在另一个答案中指出的那样)。这种使用XableY(或XingY,如BufferingPortSigningEmailSender)命名子类的方法有时可以用来描述添加新行为的有用方法。

这就是说,我认为你的问题有一个公平的暗示(不能找到一个名字),也许这不是一个好的设计决定,它试图做太多。一个班级应该“做一件事”通常是一个很好的设计原则。显然,取决于抽象的级别,可以将其扩展为包含任何内容,但是值得考虑的是:“操作若干位的设置/未设置状态”和“将位模式转换为另一种格式”计为一事情?我认为(特别是暗示你很难得到一个名字),他们可能是两个不同的责任。如果是这样,有两个类最终会变得更清洁,更容易维护(另一个规则是'一个类应该有一个改变的理由';一个类操作+ convert至少有两个理由来改变),更容易测试在隔离等。

所以不知道你的设计,我会建议也许两个类;在BitSet示例中,既有BitSet也有(比如)BitSetConverter,它负责转换。如果你想获得真正看中的,甚至可能是:

interface BitSetConverter<T> { 
T convert(BitSet in); 
BitSet parse(T in); 
} 

,那么你可能有:

BitSetConverter<Integer> intConverter = ...; 
Integer i = intConverter.convert(myBitSet); 
BitSet new = intConverter.parse(12345); 

这确实隔离的更改,使得每个不同的转换器可测试等

(中当然,一旦你这样做,你可能会喜欢看guava,并考虑使用Function,例如Function<BitSet, Integer>为一个案例,Function<Integer, BitSet>为另一个案例,然后你获得整个生态系统Function - 支持代码,可能会有用)

+0

感谢这个非常好的答案! – tyrondis 2011-05-16 13:15:43

3

我会去扩展类。这实际上就是你在做什么,用一些额外的方法扩展当前类。

至于名称:您不应该为新功能命名,因为您可能稍后添加更多功能。这是你扩展的BitSet类,所以BitSetEx已经听起来比你建议的BitSetWithConversionMethods更好。

你不想用静态方法编写一个类,这就像在OOP环境中的过程编程,并且被认为是错误的。你有一个具有特定方法的对象(比如你想做的fromByteArray()),所以你希望这些方法在这个类中。扩展是要走的路。

1

这取决于。正如nanne指出的那样,子类是一种选择。但只是有时候。字符串被声明为最终的,所以你不能创建一个子类。你有至少2个其他选项:

1)使用'封装',即创建一个类MyString,它有一个它操作的字符串(而不是扩展字符串,你不能这样做)。基本上是一个包含字符串的包装,它增加了你的功能。

2)创建一个实用程序/助手,即只有静态方法的类操作字符串。因此,像

class OurStringUtil { 
.... 
    public static int getMd5Hash(String string) {...} 
.... 

} 

看看在Apache StringUtils的东西,它遵循这一做法;这太棒了。

1

“最好的方式”有点儿主观。并且请记住,String是最终的类,因此您无法扩展它。 两种可能的方法是使用额外的方法编写诸如StringWrapper(String)的包装,或者使用静态方法(因为如果您不想直接使用util类,可以导入静态方法,因此可以导入静态方法)的某种StringUtils类。

相关问题