Private methods in Controllers [closed]
Greetings,
I've worked on quite a few apps now that are using the MVC pattern be it in Rails or .Net and I always see a bit of private methods being added inside the controller class. These private methods are really knowing the "how" do validate something or the "how" to create a view model to a domain model. It seems to me that this logic is leaking and should be placed inside helpers or into the domain model itself. I always liked the phrase "A controller should know what to do, but now how to do it." and it seems adding a bunch of private methods to the class breaks this.
I'm hoping someone has some useful insight into the matter.
Thanks!
I agree that this logic shouldn't be part of the controller. I avoid private methods in my controllers. If we take the example of "how" to create a view model to a domain model this logic normally should reside in the mapping layer.
I've used Spring MVC (3.0) and I liked how it structured servlets / web services.
It has:
- Controller
- Command object
- Validator object
Each of the @RequestMappings (public methods in the controller) acted as a web service. An HttpRequest would come in, be passed to the correct request mapping, mapped to the command object, then validated.
something like this:
GetUserCommand {
int userId;
public Map execute() {
Map result = new HashMap();
result.put("user", new UserService().get(userId) );
return result;
}
}
Controller {
@RequestMapping(value="/user")
public ModelAndView handle(GetUserCommand cmd) {
new GetUserCommandValidator().validate(cmd); //checks userid is > 0 or something
return new ModelAndView("userView", cmd.execute());
}
}
It's important to note that the HTTP request's parameters are mapped to the GetUserCommand object using reflection. So there would have to be a FrontController which figures that out, as well as figuring out which method to forward the request to.
The key thing here is that the parameters, validation, execution logic, and choice of view are separated into different components.
You can also use IoC to construct the command object with the services it requires. I eventually decided to split the Command object into a Parameters object and Command object. The Parameters object contains the userid, while the Command object is instantiated with the Parameters (and UserService) and contains the execute() method. It was more verbose, but seemed like a better separation to me.
精彩评论