为内置类型添加功能的最佳方法

时间:2011-05-15 14:33:31

标签: java oop

我想知道在严格的OOP方面,为字符串或整数或更复杂的对象(在我的例子中是BitSet类)添加内置类型的功能的最佳方法是什么。

更具体一点 - 我有两个场景:

  1. 向String对象添加md5哈希方法
  2. 将转换方法(如fromByteArray()或toInteger())添加到BitSet类。
  3. 现在我想知道实现这个目标的最佳做法是什么。

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

    现在我可以编写一个只包含执行转换的静态方法的类。

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

    那么有人能回答我这个问题吗?

4 个答案:

答案 0 :(得分:3)

我会选择扩展课程。这实际上就是你正在做的事情,用一些额外的方法扩展当前的类。

至于名称:您不应该为新功能命名,因为您可能会在以后添加更多功能。它是您的扩展BitSet类,因此BitSetEx allready听起来比您建议的BitSetWithConversionMethods更好。

您不希望使用静态方法编写类,这类似于OOP环境中的过程编程,并且被认为是错误的。你有一个具有某些方法的对象(比如你想要的fromByteArray()),所以你希望那些方法在那个类中。延伸是要走的路。

答案 1 :(得分:3)

这里有一些方法:

首先,您可以为extends BitSet课程找到更好的名称。不,BitsetWithConversionMethods不是一个好名字,但可能像ConvertibleBitSet那样。这是否表达了课程的意图和用法?如果是这样,那就是一个好名字。同样地,你可能有一个HashableString(记住你不能延伸String,正如安东尼在另一个答案中指出的那样)。这种使用XableY(或XingY,或BufferingPortSigningEmailSender)命名子类的方法有时可用于描述新行为的添加。

那就是说,我认为你的问题(无法找到一个名字)有一个公平的暗示,这可能不是一个好的设计决定,并且它试图做太多。一个班级应该“做一件事”通常是一个好的设计原则。显然,取决于抽象级别,可以拉伸以包含任何内容,但值得思考:“操纵多个位的设置/未设置状态”和“将位模式转换为另一种格式”计为一个事情?我认为(特别是暗示你很难想出一个名字)他们可能是两个不同的职责。如果是这样,拥有两个类将最终变得更干净,更容易维护(另一个规则是'一个类应该有一个改变的理由';一个类来操纵+转换至少有两个改变的理由),更容易测试孤立等等。

所以在不知道你的设计的情况下,我会建议两个班级;在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的整个生态系统 - 支持可能有用的代码)

答案 2 :(得分:1)

这取决于。正如nanne指出的那样,子类是一种选择。但有时候只是。字符串被声明为final,因此您无法创建子类。您还有至少2个其他选项:

1)使用'encapsulation',即创建一个MyString类,它有一个运行它的String(而不是扩展String,你不能这样做)。基本上是String的包装器,可以添加你的功能。

2)创建一个实用程序/帮助程序,即只使用对字符串进行操作的静态方法的类。像

这样的东西
class OurStringUtil {
....
    public static int getMd5Hash(String string) {...}
....

}

看看Apache StringUtils的东西,它遵循这种方法;太棒了。

答案 3 :(得分:1)

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