Multi-level controllers for MVC architecture

2019-06-02 06:04发布

问题:

I just encountered one of the limitations of the MVC architecture I'm currently using for my applications. Currently, my URLs look like this:

www.example.com/controller/action

Each request arrives at the front controller, which loads the requested controller class from the URL, and executes the action (method) of it. This works fine, until you need to start using nested controllers.

Example: There's a 'users' controller which holds methods like createUser(), editUser(), deleteUser() etc. All perfectly possible with the current URL structure... But what if we also need to manage user types? We would need a separate controller 'usertypes' which also holds methods like createUserType(), editUserType()... However, since user types are a part of users, the 'usertypes' controller should be nested inside the users controller, as this:

www.example.com/users/usertypes/addusertype

With the current URL structure however, this is not possible... How can I make use of nested (or multi-level if you will) controllers?

UPDATE: here's a basic representation of the application I'm working on: It's a basic business application for the administration department where they can add, view, edit and delete data from 3 categories (Promotions, Mailings and Cardholders). Each category represents a table in the database and has its own distinct fields. Accounts need to be created by the admin, users cannot create an account themselves and they can't consult their user profile.

For each of those categories I've made a controller, which holds actions like add(), edit(), getAll(), getSingle(), delete()... Each of those actions calls the appropriate methods from the Model and renders the corresponding View(s).

This was all possible with the current URL structure, which had URL's like:

example.com/promotions/add
example.com/promotions/getsingle?id=123

Recently they asked me to make it possible to also manage types of promotions, mailings and cardholders. Right now they already have a School Discount, a 20% Discount etc... But they want to add more as they wish.

This means i need a PromotionTypes controller, which also holds actions like add(), getAll(), getSingle(), delete()... It would be nice if the PromotionTypes controller could be nested in the original promotions controller, which enables URL's as so:

example.com/promotions/promotiontypes/add

instead of

example.com/promotiontypes/add

With my current front loader, this is not possible, since the first part of the URL automatically gets treated as the controller, and the second part as the action to execute from it.

回答1:

It seems like you have tied the controllers not to the view but to each domain object.

Also, what's with the strange routing? Why not :

POST "www.example.com/profile/42/type"

Because you are adding a types to the profile of specific user. This translates to execution of method postType() on the Profile controller.

If you are building your own routing mechanism, maybe this answer could be helpful.

The bottom line is this: you do not need such strange controller-of-controllers. What you need is to start looking at what sort of views you have , and then creating controller for each of them, instead of starting by looking at model layer.



回答2:

You don't mention whether you are using a framework, but the normal way would be to have the "router" apply special handling to the exceptions, e.g. Zend Framework routers