Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: pass parameter in constructor or method?

Currently I have a class, TransactionData, which is just a little bit more than a POJO. I build the object from an HTTPServletRequest. What I do:

public class TransactionData
{

    // ...

    public TransactionData(HttpServletRequest request) throws IOException
    {
        // do actual work here
    }

}

There many WTF here, the most disturbing one is that the object TransactionData is tightly coupled to HTTPServletRequest. What I thought: create an interface, TransactionDataExtractor, with an extract() method, so that I might implement different classes to build the object.

public interface TransactionDataExtractor
{
    public TransactionData extract();
}

But how do I pass the stuff needed to build the TransactionData to every implementation? The firt thing that came to mind was to use the different constructors, like this:

public class TransactionDataExtractorRequest implements TransactionDataExtractor
{
    private HttpServletRequest httpRequest;

    public TransactionDataExtractorRequest(HttpServletRequest httpRequest)
    {
        this.httpRequest = httpRequest;
    }

    public TransactionData extract()
    {
        // do whatever is required
    }

}    

But in this case whenever I need to build a new TransactionData object I have to create a new TransactionDataExtractorRequest. An implicit dependency I don't like at all. The other alternative I could think of was passing an Object parameter to extract() and cast it whenever required, giving up the type safety and introducing a lot of boiler plate ugly code

    public TransactionData extract(Object o)
    {
        HttpServletRequest h;
        if (o instanceof HttpServletRequest)
        {
             h = (HttpServletRequest)o;
        } 
        //...
    }

I don't know if I have made myself clear. I do feel like I'm missing something, I know the solution is very simple but I can't get hold of it. Any thoughts? TIA.

EDIT: the problem might even be that my hunch is completely wrong and I may dismiss it without any regret

like image 259
Manrico Corazzi Avatar asked Apr 20 '26 01:04

Manrico Corazzi


2 Answers

If your only problem is ensuring type safety when passing the source object to extract(), you can use generics:

public interface TransactionDataExtractor<E> {
    public TransactionData extract(E source); 
} 

public class TransactionDataExtractorRequest 
    implements TransactionDataExtractor<HttpServletRequest> {
    public TransactionData extract(HttpServletRequest source) { ... }
} 
like image 143
axtavt Avatar answered Apr 22 '26 15:04

axtavt


I do feel like I'm missing something ... Any thoughts?

Well my thought is that you are attempting to solve a problem that isn't really a problem. There's no obvious (to me) reason why the coupling you are trying to get rid of is actually harmful. Certainly, your attempts to remove the coupling are not making the code any easier to understand.

like image 35
Stephen C Avatar answered Apr 22 '26 15:04

Stephen C



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!