Model-View-Controller (MVC) is a classic design pattern often used by applications that need the ability to maintain multiple views of the same data. The MVC pattern makes a separation of objects into one of three categories: models for maintaining data and the business logic that works on them, views for displaying data, and controllers for handling events that affect the model or view(s).
The MVC pattern depends on an event model, allowing to define at runtime what code gets called when an event occurs. This adds lots of flexibily in a situation where the abilities of the View components are relatively fixed. This is generally the case with traditional GUI libraries.
Sometimes the MVC pattern is interpreted to have single Controller object to hold many or all event handlers related to a View. This initially simplfies the design of the user interface code, but eventually will lead to a big mess of code in the model. The model itself is a business model that dedicated to modeling a business domain, not a single object for each view.
With HTML, there is much more freedom of expression with respect to the Views. At the same time the need for a design pattern to separate the graphical side of View logic from application specific view population & refresh has been eliminated: Nowadays the View components are the DOM objects that live inside the browser. All events are channeled through a single channel of HTTP requests, and in many cases large parts, if not all, of the DOM is simply destroyed and replaced by new objects built from the HTML that is produced by the serverside application.
Then why do we for Web Pages we still try to follow that same pattern? I think some freedom of interpretation is necessary here. The main purpose of MVC nowadays is to separate Lay Out from application logic. PhpPeanuts does this by including skins. The skins make calls to their page or part object. This is much like event handling. Only the events are not formalized, all calls happen because the php interpreter is executes certain php code during inclusion of the skin. An exception is PntTablePart, which supports explicit event handlers to override it's composition from frequently repeated pieces.
HTML user interfaces have their own specific problems that need to be solved:
- the close coupling of url's to the web pages / types of the handling objects makes specialization troublesome in an application that has already been built (you have to change all the urls and forms that inlcude the handler type). This is also the main reason not to use many php scripts: you have to refer to them direcly in urls, if you refactor part of a script to a different one, you find yourself changing all those urls.
- the web page is a too large unit for reuse of layout and user interface logic. Smaller units are necessary, but do not come as naturally as with GUI components, with HTML there is too much freedom and too little ready-made funcionality. In other words, someone has to develop the components, and they should to be smart in order to make developers more productive. Becuase Customers DO ask for functionality, not for nice software architecture.
PhpPeanuts solves these problems to a great extent. In the first place a Front Controller (Site). It dispatches the single stream of http requests to the right objects that should handle them. It generally dispatches to Page objects. In case changes are requested to the model, these are handled by actions, then the request is forwarded or redirected to a page. The Front Controller will try to instantiate specific pages or actions, but if these are not present it will instantiate generic ones.For more information see the page about request dispatch.
Furthermore pages are composed of parts. Each part may have its own skin. Part inclusion itself is simply started from the larger part, page or skin by calling the printPart method. Here the page or part on which the method is called acts as the controller. Like with request dispatch the printPart method tries to get a specific part, but if it does not exist, it will get a generic one. Further specalization is possible by adding a specific method that customly handles the printing of the part. For more information see how to pecialize a part of a page.
By specialization of pages, actions and parts, the reaction of the application to an url can be changed without having to change the url itself. Composition of pages and parts offers a structured way of implementing the controllers within the MVC pattern. However, by following the graphical composition of the page it sort of repeats the 'one controller object per view' design on a smaller scale. Where this is a limitation explicit delegation to helper objects is necessary. An example of this is the use of a PntPagerButtonsListBuilder object by PntIndexPage and PntSearchPage and PntSessionBasedScout by many pages and actions for context tracking and returing to context. |