views:

156

answers:

4

for short, this could be paraphrased like "inheritance versus function library"

for example, I'd like to add a method to the javax.servlet.http.HttpServletRequest that gives me the whole body, a getBody() method that would read the body thru the getReader method, just to put an example.

In other languages, like ruby or javascript, you could add a method to the base class, or even to a specific instance, but in java I see this two choices...

  1. extend HttpServletRequest ( something like MyHttpServletRequest) and add the method

  2. or create an HttpServeletHelper static class, with static methods, with the following method

public static String HttpServeletHelper.getBody( HttpServletRequest request )

the first approach is more object oriented, and elegant, but forces you to cast your object every time you need it, and somehow you have to tell jsp to use your class...

the second approach is just a good old function library... which might be a good or bad thing depending on how you look at it...

what pros / cons do you see in each approach, and which one is the more recommended for this kind of situations?

thanks in advance

saludos

sas

+1  A: 

It depends on how you plan to use the class as to which option I'd choose. On the one hand, if you plan to insert this class into an existing processing pipeline that already uses HttpServletRequest, I'd opt for the inheritance method.

For all other situations (that I can see at the moment) I would opt for the helper class. I would not make it static, however, as static methods are notoriously difficult to test. Instead I'd implement some form of Singleton pattern with a static getter.

Randolpho
I would agree, it depends on how you plan to use it but in most cases a helper class would be the best option. I would advocate creating one instance of the helper and injecting it where necessary as opposed to a Singleton - but that's my preference
rojoca
@rojaca: Oh, I agree, that's probably the best way to implement the helper; Singleton is highly overused IMO. But... since this is for Java and if one pattern defines Java, it's Singleton the singleton pattern, I thought... Well, you know. :)
Randolpho
+5  A: 

I would choose #2. HttpServletRequest is part of a framework, so Tomcat (or whatever) is going to instantiate it and hand it to your code. You won't get to choose whether to use your subclass. (Actually, with the rise of frameworks like Servlets, EJBs, etc, I find this problem to be rather common.)

Also, a lot has been written recently about over-reliance on inheritance as an anti-pattern. In Java, inheritance is a "scarce resource": for each class, you only get to do it once. You should reserve inheritance for things that are genuinely "sub-classes," not just to add some functionality here and there.

Paul A Jungwirth
+2  A: 

Your particular example suffers from at least one problem: servlet/JSP engines won't know or care about your subclass. They'll only deal with HttpServletRequest. I suppose you can wrap it and cast it, but I'd hardly call that "elegant".

You don't even cite another possibility: composition. You can have a class that's non-static that takes an HttpServletRequest as a ctor argument and defers to it as implementation of the ServletRequest methods. You add in the additional getBody call to perform your specialized behavior.

Maybe reading this will help.

There are other SO questions about preferring composition over inheritance. See what you think of those.

I would go with the helper class for this particular example as well, but god forbid a Singleton. It's not really necessary or desirable.

This example feels especially awkward. Is this really what you want to do?

duffymo
Jinx! Posted the same link.
Apocalisp
Great minds, thinking alike...
duffymo
so far now I've solved it with the second option, a helper class... why do you find it so odd??? am I missing anything?
opensas
on the other hand, I'll check your link, seems like I've missed an interesting option... thanks!
opensas
+2  A: 

See GoF on Composition vs Inheritance. The one thing to take away from the Design Patterns book is to always favour composition over inheritance. The reason that inheritance feels more "elegant" is that the type system already implicitly converts from subtypes to supertypes for you. But you run into a limitation in that you lock yourself into a specific hierarchy that becomes extremely resistant to change.

Where you need polymorphism, use parametric polymorphism via generics rather than implicit type polymorphism via subclassing.

Apocalisp
+1 from me. Sounds like fine advice.
duffymo