PHP Objects, Patterns and Practice (3rd edition)

(Barry) #1
CHAPTER 12 ■ ENTERPRISE PATTERNS

Having said that, once you have successfully deployed a Front Controller in one project, you will
find that you can reuse it for others with lightning speed. You can abstract much of its functionality into
library code, effectively building yourself a reusable framework.
The requirement that all configuration information is loaded up for every request is another
drawback. All approaches will suffer from this to some extent, but Front Controller often requires
additional information, such as logical maps of commands and views.
This overhead can be eased considerably by caching such data. The most efficient way of doing this
is to add the data to your system as native PHP. This is fine if you are the sole maintainer of a system, but
if you have nontechnical users, you may need to provide a configuration file. You can still automate the
native PHP approach, though, by creating a system that reads a configuration file and then builds PHP
data structures, which it writes to a cache file. Once the native PHP cache has been created, the system
will use it in preference to the configuration file until a change is made and the cache must be rebuilt.
Less efficient but much easier is the approach I took in the ApplicationRegistry class—simply serialize
the data.
On the plus side, Front Controller centralizes the presentation logic of your system. This means that
you can exert control over the way that requests are processed and views selected in one place (well, in
one set of classes, anyway). This reduces duplication and decreases the likelihood of bugs.
Front Controller is also very extensible. Once you have a core up and running, you can add new
Command classes and views very easily.
In this example, commands handled their own view dispatch. If you use the Front Controller pattern
with an object that helps with view (and possibly command) selection, then the pattern allows for
excellent control over navigation, which is harder to maintain elegantly when presentation control is
distributed throughout a system. I cover such an object in the next section.


Application Controller


Allowing commands to invoke their own views is acceptable for smaller systems, but it is not ideal. It is
preferable to decouple your commands from your view layer as much as possible.
An application controller takes responsibility for mapping requests to commands, and commands
to views. This decoupling means that it becomes easier to switch in alternative sets of views without
changing the codebase. It also allows the system owner to change the flow of the application, again
without the need for touching any internals. By allowing for a logical system of Command resolution, the
pattern also makes it easier for the same Command to be used in different contexts within a system.


The Problem


Remember the nature of the example problem. An administrator needs to be able to add a venue to the
system and to associate a space with it. The system might, therefore, support the AddVenue and AddSpace
commands. According to the examples so far, these commands would be selected using a direct map
from a request parameter (cmd=AddVenue) to a class (AddVenue).
Broadly speaking, a successful call to the AddVenue command should lead to an initial call to the
AddSpace command. This relationship might be hard-coded into the classes themselves, with AddVenue
invoking AddSpace on success. AddSpace might then include a view that contains the form for adding the
space to the venue.
Both commands may be associated with at least two different views, a core view for presenting the
input form and an error or “thank you” screen. According to the logic already discussed, the Command
classes themselves would include those views (using conditional tests to decide which view to present in
which circumstances).

Free download pdf