Application layer design: Is it more beneficial to have one action per class?

Well lately I read an article by Paul M. Jones, which was about Action-Domain-Response, an architecture design alternative to Model-View-Controller. The author makes some very interesting point, and the link can be found below:
http://paul-m-jones.com/archives/5970

What intrigues me the most at this point is that in this ADR pattern(as opposed to MVC), the author uses one action per class, while in a traditional MVC pattern we will use multiple actions in one controller class, while each action itself will be just one method, rather than one class. I wonder, is it a better practice to have one action per class(action as class), or multiple action per class(action as method)? Which one do you think is better in your eyes? What are the major pros and cons to have action classes, rather than action methods in controller classes?

I actually went into detail on this very issue on the ADR github page: https://github.com/pmjones/adr/issues/25

In short: No, one class per action leads to repeated code. You should have one controller per view.

First, a quick disclaimer for all involved in this thread: My response assumes we’re talking about the traditional, web MVC.

With that out of the way, I think one vs many actions per class depends on whether you want your controllers to use a service locator or be a dependency injected service.

If you want your controllers to be a dependency injected service, then one action per class is the way to go. If you had multiple actions, then the controller’s constructor would have to accept dependencies that any of the actions might need. You could end up in a situation where one of the actions requires the database, which means the constructor would have to require it, but the action you actually invoke might not need it. One action per class means the action’s dependencies and the constructor’s arguments would match up.

But if your controllers were using service locator – which is enormously common in controllers; literally every framework I can think of, even those that allow for controllers to be dependency injected services, still use service locator most of the time for convenience – then the problem I described in the previous paragraph wouldn’t exist anymore. Each action would pull in its own dependencies without requiring anything from the constructor. In this scenario, you could have multiple actions per class without any problems.

Why would your controller ever need a dependency other than a model and potentially a request object that was a wrapper for $_POST/$_GET?

The minimal amount of dependencies make it far more reasonable to inject the few dependencies and following SRP all the actions should require the same set of dependencies.

edit:

how is:

public function __construct(ServiceLocator $serviceLocator) {
   $this->sl = $serviceLocator();
}

public function action() {
    $dependency = $this->sl->getDependency();
    $dependency->foo();
}

any more “convenient” than:

public function __construct(Dependency $dependency) {
   $this->dependency = $dependency;
}

public function action() {
   $this->dependency->foo();
}

it’s more lines of code as well as being less OO (digging into collaborators)

Its very interesting to read, thanks TomB and Jeff Mott, I know what to do now. And on a side note, it seems that Paul M Jone has replied to TomB’s argument regarding ADR:

so @TomB, do you have any comments to make about that, perhaps a counter-argument?

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.