mercredi 9 novembre 2016

Service Class Delegation

I have a basic controller(Spring MVC) that will get User data for my website. It has different endpoints that could search/add/update data in different environment datasources. My issue is that depending on configuration values I need to only read and return a list of User data from certain environments(among other functionalities omitted from this post).

I have set up a base interface for getting User detail, and have implementations for every datasource that I need to go out to.

public interface BaseUserService {
    //user service interface
}

@Service
public class EnvironmentAService implements BaseUserService {
    // do datasource specific dao stuff.
}

@Service
public class EnvironmentBService implements BaseUserService {
    // do datasource specific dao stuff.
}

@Service
public class EnvironmentCService implements BaseUserService {
    // do datasource specific dao stuff.
}

Currently in my controller I am doing something like this:

@RestController
@RequestMapping("api")
public class UserController {

    @Autowired
    ConfigurationService configurationService

    @Autowired
    BaseUserService environmentAService;

    @Autowired
    BaseUserService environmentBService;

    @Autowired
    BaseUserService environmentCService;

    @RequestMapping(value = "/users", method = RequestMethod.GET,  headers={"Accept=application/json,application/xml"})
    public List<User> userList(
            @RequestParam(value="configValue") String configValue,
            @RequestParam(value="username") String username,
            @RequestParam(value="lastName") String configValue,
            @RequestParam(value="dob") Date dateOfBirth
            ){

        Configuration config = configurationService.getConfiguration(configValue);

        if(config.value == null)
            throw new ConfigurationNotFoundException("Please enter a valid configuration value");

        List<User> userList = new ArrayList<User> users;

        if(config.environments.contains(Environment.A))
            userList.addAll(environmentAService.getUserList(username,configValue,dateOfBirth));
        if(config.environments.contains(Environment.B))
            userList.addAll(environmentBService.getUserList(username,configValue,dateOfBirth));
        if(config.environments.contains(Environment.C))
            userList.addAll(environmentCService.getUserList(username,configValue,dateOfBirth));

        return userList;
    }
}

This works fine, but I am looking for a more elegant solution, so the controller isn't so tied to the service classes. I was looking into delegate and decorator pattern to maybe house conditionals in one class, but these seem like they won't work, or I'm not exactly sure on how to implement it in my case.

Aucun commentaire:

Enregistrer un commentaire