Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 重构到依赖注入_Java_Dependency Injection_Refactoring - Fatal编程技术网

Java 重构到依赖注入

Java 重构到依赖注入,java,dependency-injection,refactoring,Java,Dependency Injection,Refactoring,我有一段代码,我想把它重构成依赖注入风格 目前看起来是这样的: class MyService { public void A(Account account, String someparam1, int someparam2) { AccountHandler myHandler = new AccountHandler(account); // Do something with AccountHandler... myHandle

我有一段代码,我想把它重构成依赖注入风格

目前看起来是这样的:

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
}
一种方法是注入
AccountHandler
并为每个方法设置帐户:

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);
    }
}
我觉得这很奇怪
AccountHandler
是(或可能是)一个单例,但它仍然有一些状态。理论上,在另一种方法中,可能会“忘记”调用
setAccount
,而不会出现问题,因为以前的服务方法设置了它(当然,除非您指定它应该是原型范围的,但仍然…看起来很奇怪)

这只会将问题推送到
AccountHandler
。要么
AccountHandler
本身在
someMethod1/2
的开头执行
this.setAccount(account)
,要么它可以让每个方法都没有副作用,这意味着它实际上没有任何状态。这听起来没什么,但我觉得我误解了什么

我认为最惯用的是:

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

    public void someMethod1(String someparam1);
    public void someMethod2(int someparam2);
}
其中,
AccountHandler
类似于:

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

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

在调用
MyService
方法之前,我会将
Account
放在
IoC
-容器的范围内。我不知道您在
Java
中是如何做到这一点的。任何指针都将不胜感激。

您可以注入一个具有createAccountHandler(Account)方法的AccountHandlerFactory,AccountHandlerFactory将是一个无状态的单例,您的AccountHandlerFactory将是有状态的,但是单个对象。

是的,这也是我最初的想法。尽管在谷歌搜索之后,传统观点似乎认为工厂模式和依赖注入是解决同一问题的不同解决方案。我没见过其他人在工厂里使用DI?我看到Spring有一个叫做BeanFactory的东西,但不确定它是否适用于这个用例。为什么不呢?我一直看到它,通常如果你创建一个工厂,你会创建一个工厂接口,例如,你会有一个AccountHandleFactory接口和我提到的方法,然后你会有DatabaseBackedAccountHandlerFactory和HttpBasedAccountHandlerFactory实现,你可以使用DI framewok轻松地交换它们。而且它还使您的代码更易于测试。BeanFactory是一个特定于spring的东西,如果你想与spring紧密结合,你可以为AccountHandler创建一个原型范围的Springbean,这需要一些思考,但是是的,我同意。这显然是最好的解决办法。如果AccountHandler本身有我不希望工厂处理的其他依赖项,我确实会担心会发生什么。然而,这是另一天的问题。