Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refactoring to dependency injection

I have a piece of code which I want to refactor into a dependency injection style.

It currently looks like this:

class MyService {
    public void A(Account account, String someparam1, int someparam2) {
        AccountHandler myHandler = new AccountHandler(account);

        // Do something with AccountHandler...
        myHandler.someMethod1(someparam1);
        myHandler.someMethod2(someparam2);
    }

    // Some more methods with same signature
}

One way would be to inject the AccountHandler and set the account for each method:

class MyService {

    @Inject
    AccountHandler myHandler;

    public void A(Account account, String someparam1, int someparam2) {
        myHandler.setAccount(account);

        // Do something with myHandler
        myHandler.someMethod1(someparam1);
        myHandler.someMethod2(someparam2);
    }
}

This seems weird to me. AccountHandler is (or could be) a singleton, but it would still have some state. Theoretically it would be possible in a different method to "forget" to call setAccount without issues because the previous service-method set it (unless you of course specify that it should be prototype-scoped, but still... seems weird).

class MyService {

    @Inject
    AccountHandler myHandler;

    public void A(Account account, String someparam1, int someparam2) {

        // Do something with myHandler
        myHandler.someMethod1(account, someparam1);
        myHandler.someMethod2(account, someparam2);
    }
}

This only pushes the issue to AccountHandler. Either AccountHandler would itself do a this.setAccount(account) at the beginning of the someMethod1/2, or alternatively it could have every method be side-effect free, meaning it doesn't actually have any state. This sounds okay-ish, but I'm feeling like I've misunderstood something.

What I think would be the most idiomatic would be something like:

class MyService {
    public void A(@Inject AccountHandler myHandler, String someparam1, int someparam2) {
        // Do something with myHandler
        myHandler.someMethod1(someparam1);
        myHandler.someMethod2(someparam2);
    }
}

Where AccountHandler would be something like:

class AccountHandler {
    @Inject
    Account account;

    public void someMethod1(String someparam1);
    public void someMethod2(int someparam2);
}

Somewhere before I call the MyService method I would put Account on the IoC-container's scope. I have no idea of how you'd actually do this in Java. Any pointers would be greatly appreciated.

like image 981
Knut Saua Mathiesen Avatar asked Dec 19 '25 22:12

Knut Saua Mathiesen


1 Answers

You could inject an AccountHandlerFactory that has a createAccountHandler(Account) method, and the AccountHandlerFactory would be a singleton which is stateless and your AccountHandlers will be statefull but single objects.

like image 171
maczikasz Avatar answered Dec 21 '25 10:12

maczikasz



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!