0
\$\begingroup\$

Well, the questions is a little bit broader, so I'll assume that the basics is already defined:

Controller

  1. FrontController
  2. Controllers (plugin hooks, request/response object, view handler)

View

  1. View (template, scripts, partials, helpers)

Model

  1. Domain model objects
  2. Domain model repository
  3. Database abstraction layer

Let me know if I missed something.

Assuming that the above is correct. Now the big question:

Should controllers implement business logic?

// (an example in php)
class UsersController {
   public function create() {
      $user = new User();
      $user->setName($this->getRequest()->getPost('name'));
      // ...
   }
}

The point is, the create action is deciding which information a user need to be created. Therefore, I'm assuming that it's business logic.

// (an example in php just delegating the job to the repository)
class UsersController {
   public function create() {
      $this->userRepository->create($this->getRequest->getPost());
   }
}

If we delegate the job to the repository, then I'm assuming that now the controller is just doing its job, no business logic in there.

Now the second question. Should repositories deal with create, edit and delete operations?

Finally, it will be common for repositories to populate associations and aggregations. So the user repository can also populate the user object with its article associations, for instance. In this case, should the repository call the article repository to do so?

Now about the aspect oriented programming:

We need to deal with ACLs. Whether a domain object or collection is accessible by the current user is determined by the ACLs.

Isn't it part of the model?

Should controller implement ACL's checks as a plugin hooked on the pre-dispatch or, since it's business logic, should our repositories know if its methods are accessible by the current user?

Now what I achieved so far

Well, I ended up with a service layer with protected methods like:

class UsersService extends AbstractService {
   protected function _create($data) {
       $this->validate($data)
       $this->userRepository->create($data);
   }
}

and with a overloading (again in php, but in java for instance, we'd assume a proxy)

class AbstractService {
    public function __call($method, $args) {
       // ACLs checks
       // then call the protected method
    }
}

My service layer is responsible to hold validations and ACLs checks.

So in the end:

class UsersController {
   public function create() {
      $this->userService->create($this->getRequest->getPost());
   }
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Should controllers implement business logic?

That depends on your design and style of doing things "your" MVC-way. As you're designing a framework you should probably allow both to keep the usage of the framework flexible.

Taking a closer look on your code examples I'd say you're only shifting things around anyway. Why do you have a controller when you use it to access the request? Shouldn't the request lead into the controller call and the controller should not care at all about the request any longer? Just a counter question, if you want to make your framework strict for some reason, think about why.

Now the second question. Should repositories deal with create, edit and delete operations?

Normally that's within the domain of a repository, but whatever suits your design needs, a repository could be just a delegate to different create, edit and delete components as well. Application-wise it shouldn't make a difference whether or not, so probably do a risk analysis and then decide which part of the question you actually need to answer now or if you can solve this by just deciding now, and if the future shows that your design needs change, change your design.

We need to deal with ACLs. Whether a domain object or collection is accessible by the current user is determined by the ACLs.

Isn't it part of the model?

Sure, it's part of the model, the ACL Domain Model (and explicitly not other models).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.