So I'm working on my own "MVC" framework for learning purposes and for personal use. I use the "MVC" expression as a concept not a concrete design pattern. So I refer to MVC as a "separation concept" not a concrete thing since (mainly in the world of web) the implementation can be different in every framework.
I have concrete question (you can find it at the bottom of this long post - sorry for that) but first, I want to show you my current implementation. So here it is:
The htaccess rewrite rule says that everything (which is not a file or a directory) is passed to the index.php (bootstrap). A RouterRouter instance is created and asked to process the urlURL and render the page.
The specific ControllerController instance is instantiated by and its method is called by the RouterRouter. The RouterRouter extract the controller and action name from the urlURL. Example:
Example:
is "translated to":
I have a concrete ViewView class which is pretty simple, I can add, remove and get custom data which is used when the page is rendered, something like this:
The Model layer is the data representation and storage layer. I split up the persistancepersistence and representation. So I have a concrete class (like User) which represents a single user. I also have a UserServiceUserService class which is used to add/remove/modify/query user to/from the database or memory or anything (because it's an abstract class, different implementations can be created).
Because I want to write less boilerplate code I've created a simple "class inspector" class. It can be used to get (and parse) the doc comment of a class, its functions and fields. I use this inspector in the base Model class to "generate" automatic getters and setters. This place can be used to final-validate data.
Code example:
The RouterRouter creates a new controller and call its action. The ControllerController creates the corresponding view instance and pass the model layer's data to it as a function parameter. The ViewView instance then loads the required template file, set the data which is required by the template (strong coupling).
I also created a ServiceContainerServiceContainer class which is used by the controllers. Because the Controller is instantiated by the Router I cannot use direct dependency injection and this was my solution for this problem.
Here comes a simple example of a one-way data flow. The UserControllerUserController creates the UserView and call its viewUser(id)viewUser(id) function which loads the required template, sets the "presentable" data and done.
1)
As you can see I totally separated the Model from the View Template, so the actual rendering does not know about the data in the Model layer. This looks good for me because of the separation. And also sometimes I want to preprocess the data before sending it to rendering (like creating the correct date format and so on) and this can be done in the View. Is this a good idea?
2)
The example shows a "one-way data flow" but what's about the forms? I have a register() function in the UserController as well. It asks the UserView to read the form data (and check if it was sent at all). I've done this in the UserView because the UserController does not know about the concrete form. Where should I validate the data? Before HTML5 the input fields of a form are sent as simple strings without restrictions (expect the radio buttons and these of course).
As you can see I totally separated the Model from the View Template, so the actual rendering does not know about the data in the Model layer. This looks good for me because of the separation. I also sometimes want to preprocess the data before sending it to rendering (like creating the correct date format and so on) and this can be done in the View. Is this a good idea?
The example shows a "one-way data flow" but what's about the forms? I have a
register()function in theUserControlleras well. It asks the UserView to read the form data (and check if it was sent at all). I've done this in the UserView because theUserControllerdoes not know about the concrete form. Where should I validate the data? Before HTML5 the input fields of a form are sent as simple strings without restrictions (except the radio buttons and these of course).
I would put the validation in the ControllerController. If I do that in the ControllerController, I can check the incoming input with a pattern (eg. allow only letters and numbers for a username), check the length of the string (but this is determined by the model, isn't it?) and the most important aspect is that I can use the Model and Service directly to validate the data (eg. do not allow duplicated username).
Do you think it's a good idea to put the validation in the controller? My problem with the validation in the controller is that if the Model is (for some reason, so don't ask why) modified directly without using the Controller's function then the data wouldn't be validated.
