Best approach to extending class functionality in java?

it can be rephrased as "inheritance and function library"

for example, I would like to add a method to javax.servlet.http.HttpServletRequest that gives me the whole object, the getBody () method, which will read the body through the getReader method, just to give an example.

In other languages, such as ruby โ€‹โ€‹or javascript, you can add a method to a base class or even to a specific instance, but in java I see two options ...

  • extend HttpServletRequest (something like MyHttpServletRequest) and add a method

  • or create a static class HttpServeletHelper with static methods with the following method

public static String HttpServeletHelper.getBody (HttpServletRequest request)

the first approach is more object oriented and elegant, but it forces you to throw 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 library of functions ... which may be good or bad depending on how you look at it ...

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

+4
source share
4 answers

In your specific example, there is at least one problem: the servlet / JSP engines will not know or care about your subclass. They will only deal with the HttpServletRequest. I suppose you can wrap it and drop it, but I would hardly call it "elegant."

You do not even refer to another possibility: composition. You may have a class that is non-static, which takes an HttpServletRequest as an argument to ctor and refers to it as an implementation of the ServletRequest methods. You add an extra getBody call to execute your custom behavior.

Maybe reading this will help.

There are other questions regarding the preference of composition over inheritance. See what you think of them.

I would go with a helper class for this particular example, but God forbid Singleton. This is not necessary or desirable.

This example seems especially inconvenient. Is this really what you want to do?

+2
source

I would choose # 2. HttpServletRequest is part of the structure, so Tomcat (or something else) is going to create an instance and pass it to your code. You will not be able to choose whether to use your subclass. (In fact, with the growth of frameworks such as Servlets, EJB, etc., I find this problem quite common.)

In addition, a lot has recently been written about the excessive dependence on inheritance as an anti-pattern. In Java, inheritance is a "scarce resource": for each class, you can only do this once. You should reserve inheritance for things that are truly โ€œsubclasses,โ€ and not just to add some functions here and there.

+5
source

See GoF on Composition vs Inheritance . The only thing you need to remove from the Design Patterns book is to always maintain composition over inheritance . The reason why inheritance seems more "elegant" is because the type system is already implicitly being transferred from subtypes to supertypes for you. But you are faced with the limitation that you block yourself in a certain hierarchy that becomes extremely resilient to change.

If you need polymorphism, use parametric polymorphism through generics, rather than an implicit type of polymorphism through a subclass.

+2
source

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

For all other situations (which I can see at the moment) I would choose a helper class. However, I would not become static, since static methods are usually difficult to verify. Instead, I would use some form of Singleton template with a static getter.

+1
source

Source: https://habr.com/ru/post/1286604/


All Articles