在Java中扩展类功能的最佳方法?

时间:2009-06-23 00:57:06

标签: java inheritance function

简而言之,这可以解释为“继承与函数库”

例如,我想在javax.servlet.http.HttpServletRequest中添加一个方法,它给我整个身体,一个getBody()方法,它将通过getReader方法读取正文,只是为了举个例子

在其他语言中,比如ruby或javascript,你可以在基类中添加一个方法,甚至添加到特定的实例,但在java中我看到了这两个选择...

  1. 扩展HttpServletRequest(类似于MyHttpServletRequest)并添加方法

  2. 或使用静态方法创建一个HttpServeletHelper静态类,使用以下方法

  3. public static String HttpServeletHelper.getBody(HttpServletRequest request)

    第一种方法更面向对象,更优雅,但强迫你在每次需要的时候投射你的对象,不知怎的,你必须告诉jsp使用你的类......

    第二种方法只是一个很好的旧功能库......根据你的看法,它可能是好事还是坏事......

    您在每种方法中看到的利弊是什么,在这种情况下哪一种更受推荐?

5 个答案:

答案 0 :(得分:5)

我会选择#2。 HttpServletRequest是框架的一部分,因此Tomcat(或其他)将实例化它并将其交给您的代码。您无法选择是否使用您的子类。 (实际上,随着Servlet,EJB等框架的兴起,我发现这个问题相当普遍。)

此外,最近有很多关于过度依赖继承作为反模式的文章。在Java中,继承是一种“稀缺资源”:对于每个类,您只能执行一次。你应该保留对真正“子类”的东西的继承,而不仅仅是在这里和那里添加一些功能。

答案 1 :(得分:2)

您的特定示例至少会遇到一个问题:servlet / JSP引擎不会知道或关心您的子类。他们只会处理HttpServletRequest。我想你可以将它包起来并投下它,但我几乎不称它为“优雅”。

你甚至没有引用另一种可能性:构图。您可以拥有一个非静态类,它将HttpServletRequest作为ctor参数,并将其作为ServletRequest方法的实现。您可以添加额外的getBody调用来执行您的专门行为。

也许阅读this会有所帮助。

还有其他关于优先考虑构成而非继承的问题。看看你对这些的看法。

我也会参加这个特定例子的帮助类,但是上帝禁止使用Singleton。这不是必要或不可取的。

这个例子感觉特别尴尬。这真的是你想要做的吗?

答案 2 :(得分:2)

See GoF on Composition vs Inheritance。从设计模式一书中剔除的一件事就是始终倾向于合成而不是继承。继承感觉更“优雅”的原因是类型系统已经隐式地从子类型转换为超类型。但是你遇到了限制,因为你将自己锁定在一个特定的层次结构中,这个层次结构变得极其容易抵抗变化。

在需要多态性的地方,通过泛型使用参数多态,而不是通过子类使用隐式类型多态。

答案 3 :(得分:1)

这取决于您打算如何使用该类选择我选择的选项。一方面,如果您计划将此类插入已使用HttpServletRequest的现有处理管道中,我将选择继承方法。

对于所有其他情况(我现在可以看到),我会选择帮助类。但是,我不会让它静止,因为静态方法非常难以测试。相反,我会使用静态getter实现某种形式的Singleton模式。

答案 4 :(得分:0)

Oop中的所有内容都会使用功能样式来结束或结束。重构直到以负责任的态度达成目标意味着很多小的方法或扩展。接下来,您唯一需要考虑的就是SOLID中的O。使该方法成为其他类的扩展,以易于使用,并建立扩展库lib(您自己的工具箱)。