Well lately I’ve been writing some ASP.NET MVC code, I noticed that the controller actions are defined much more easily and cleanly since C# supports method overloading and data annotation. Take an example of the edit action for user profile, in ASP.NET MVC you would define it like this:
public ActionResult Edit(int? id){
//code for the default edit action.
}
[HttpPost]
public ActionResult Edit(UserProfile $profile){
//code for edit action when a form is submitted.
}
This way, handling controller actions based on whether the user has submitted a form in a view page is very straightforward. Unfortunately, it is not possible with PHP, and in many PHP frameworks we have to use an if condition to check whether a forum is submitted, like this:
public function edit($id = NULL){
if($this->request->method == "POST"){
//action for form processing.
}
else{
//default action for edit.
}
}
Of course with return statement the else block can be omitted to make this look slightly better, it is still a bad design, especially considering the same if condition is checked in many controllers and actions for a typical application(unless your entire site has one and only form). The presence of this if statement itself is a code smell, and I definitely want to avoid it. Since PHP does not support method overloading, it’s impossible to apply the same technique in ASP.NET here.
I know there are several alternatives to remove the if statement. One way is to prefix or suffix the action method with HTTP method, thus splitting the action into two methods with different names, such as editGet() and editPost(). The controller’s base/parent class can intercept calls to action to determine which version of the action method to invoke. Another approach is to create action as class rather than method, and the action class can have methods such as get() and post(), or maybe even more, to handle different branches for a controller action. A third alternative is similar to the second one, but to split the controller into two controller, one GetController and one PostController, so the interception of action method based on request method is handled at controller level.
But the question is, what is the best solution to this problem? Of course I can stick to checking request method condition at each controller method, but as I said before I dont like it, repeated checks of the same if condition violates basic OOP principle, the presence of such an if condition is a code smell. But the three alternatives I brought up above all have issues as well, either making the interface ugly, or to introduce unnecessary complexity to the application. Do anyone of you know if there are better alternatives? If not, which one of the three alternative solutions I should look for? Thnks.