【发布时间】:2019-01-10 17:50:56
【问题描述】:
我有一个控制器,它有 4 个非常相似的方法,调用远程服务器上的 API 来对不同类型的用户执行不同的操作。这些 API 调用之间的变化只是端点和一些参数。
因此,这 4 个方法都以非常相似的代码调用服务:它们从服务器获取令牌、设置参数、返回 API 的响应。由于稍后将添加更多操作,我决定使用使用工厂方法模式创建 ServiceFactory 并在服务上使用模板模式以避免代码重复。
我的问题是,为了让工厂自动装配服务,它需要与它们耦合,我必须@Autowire 每次实现。有没有更好的解决方案?
这是我目前的代码:
休息控制器
@RestController
public class ActionController {
@Autowired
private SsoService ssoService;
// this is the factory
@Autowired
private ServiceFactory factory;
@PostMapping("/action")
public MyResponse performAction(@RequestBody MyRequest request, HttpServletRequest req) {
// template code (error treatment not included)
request.setOperator(ssoService.getOperator(req));
request.setDate(LocalDateTime.now());
return serviceFactory.getService(request).do();
}
}
服务工厂
@Component
public class ServiceFactory {
@Autowired private ActivateUserService activateUserService;
@Autowired private Action2UserType2Service anotherService;
//etc
public MyService getService(request) {
if (Action.ACTIVATE.equals(request.getAction()) && UserType.USER.equals(request.getUserType()) {
return activateUserService;
}
// etc
return anotherService;
}
}
Service Base,实现MyService接口
public abstract class ServiceBase implements MyService {
@Autowired private ApiService apiService;
@Autowired private ActionRepository actionRepository;
@Value("${api.path}") private String path;
@Override
public MyResponse do(MyRequest request) {
String url = path + getEndpoint();
String token = apiService.getToken();
Map<String, String> params = getParams(request);
// adds the common params to the hashmap
HttpResult result = apiService.post(url, params);
if (result.getStatusCode() == 200) {
// saves the performed action
actionRepository.save(getAction());
}
// extracts the response from the HttpResult
return response;
}
}
服务实现(有4个)
@Service
public class ActivateUserService extends ServiceBase {
@Value("${api.user.activate}")
private String endpoint;
@Override
public String getEndpoint() {
return endpoint;
}
@Override
public Map<String,String> getParams(MyRequest request) {
Map<String, String> params = new HashMap<>();
// adds custom params
return params;
}
@Override
public Action getAction() {
return new Action().type(ActionType.ACTIVATED).userType(UserType.USER);
}
}
【问题讨论】:
-
似乎您担心在
ServiceFactory中注入许多UserService实现,但从您描述的内容和您发布的代码来看,似乎所有4 个MyService实现实际上都有相同的逻辑,不同之处只是它们的配置数据。如果是,您可以创建一个接受配置参数的单个实现 .... -
@KenChan 啊,很抱歉这么久才回复您的评论。确实,如果只是配置更改,最好使用配置参数。但这并不是唯一的区别——尽管非常相似,
getParams方法中的实现也发生了变化。因此,拥有一个服务也需要大量的 ifs,或者根据执行的操作使用策略模式——这与我接受的解决方案类似。
标签: java spring factory-method