My two cents:
- Use autowired constructor injection as recommended by the Spring team. Doing this makes it very visible when your controller is getting bloated (see the next point)
- Have no more than 3 dependencies in the constructor as suggested by Bob Martin in his book Clean Code. If you have more, then your controller is probably violating the single responsibilty principle.
- If you want your controller to do more then you should probably put that functionality in a second controller!
A crude example:
@RestController
public class PetShopController {
@Autowired private DogService dogService;
@Autowired private CatService catService;
@Autowired private MonkeyService monkeyService;
@Autowired private FishService fishService;
// all three services above are dependent on the two below
@Autowired private PetInsuranceService petInsuranceService;
@Autowired private PetOwnerService petOwnerService;
//..and so on
}
Change to:
@RestController
public class DogsController {
private DogService dogService;
//the insurance/owner services have been split into one service/pet type
private DogInsuranceService dogInsuranceService;
private DogOwnerService dogOwnerService;
//I've used interfaces for types here
@Autowired DogsController(IPetService dogService,IInsuranceService dogInsuranceService, IOwnerService dogOwnerService) {
this.dogService = dogService;
this.dogInsuranceService = dogInsuranceService;
this.dogOwnerService = dogOwnerService;
}
//..and so on
// make similar controllers for other pets!!
}
I'd argue that it's not about reducing the amount of code, it's more about making sure each class has a single responsibility! Eg/ here Dogs do dog things like bark! Cats do cat things like meow!! As soon as you have a class with more than 3 deps/services that does both or more then that class needs to be split!!