Bien, ya he empezado a pasar el mini-framework a código (hasta ahora eran diagramas sobre papeles en sucio en pseudo UML, si es que se le puede llamar UML a lo que hice
). Todavía no he llegado al punto de que pueda implementar un HolaMundo, pero no me debe quedar mucho.
Por cierto, tiene muchísimo más sentido que la acción devuelva un objeto de la Vista, en vez de recuperar el String representativo desde el controlador.
Empezando de abajo a arriba, voy a tener dos jerarquías de objetos, unos hijos de AbstractAction y otros de AbstractDisplayer que esbozo a continuación (por cierto, para PHPMarker usé unos "TagHandlers" que se parecen mucho a esas clases
):
Código PHP:
class AbstractAction {
function AbstractAction(){
}
//me ayudará (re)iniciar el objeto cuando ya esté construido
function init(){
trigger_error('llamada a método abstracto');
}
//recibe una instancia de WorkData (petición+respues HTTP)
function process( &$data ){
trigger_error('llamada a método abstracto');
}
//inicializará atributos de clase
//de forma que $key es el nombre del attr.
function addPropery( $key, $value ){
trigger_error('llamada a método abstracto');
}
}
class AbstractView{
function AbstractView(){}
function init{}
function render( &$data ){}
function addProperty($key, $value){}
}
De tal forma que un supuesto HelloWorldAction heredará de AbstractAction y su correspondiente vista de AbstraView. Esto está claro.
A continuación el controlador, sólo pongo un método (porque los otros dos son el constructor "privado" y su corresondiente getInstance):
Código PHP:
class Controller {
function init(){
//esto se ejecutará una vez, cuando se invoque al constructor
//simplemente construye las factorías
//para no tener que hacerlo luego
ActionManager::getInstance();
ViewManager::getInstance();
TemplateManager::getInstance();
}
function getView( &$data ){
$mgr =& ActionManager::getInstace();
$action =& $mgr -> getAction( $data -> getParameter('action') );
$view =& $action -> process( $data );
$tmanager =& TemplateManager::getInstance();
$tmanager -> setTemplateFactory('phpTemplate');
$tmanager -> setTemplateDirectory('presentation/');
$mainview = $tmanager -> getTemplate( 'layout', 'layout.html' );
$mainview -> expose( 'view', $view) );
echo $mainview -> render();
}
}
Cosas que comentar:
1. La forma de llamar al controlador es:
Código PHP:
//index.php?action=helloworld
$data =& new WorkData();
//sí, le cambié el nombre de HttpData
$controller =& Controller::getInstance();
$controller -> getView($data)
2. ActionManager crea y mantiene las acciones
3. Hay un ViewManager que usa cada Acción para recuperar la instancia de vista que le corresponde.
4. El TemplateManager a lo mejor os suena de PHPMarker, y es que enfecto, simplemente llamando a setTemplateFactory('phpmarker') el getTemplate() me devolvería una instancia que interpreta esa clase plantillas.
Pero como por lo pronto está en fase "experimental", uso una clase muy simple (como la del artículo de Sitepoint: beyond the template engine) que abstrae una típica plantilla con PHP para represenar la lógica de la presentación.
De esta forma, es posible usar cualquier motor de plantillas, siempre que se implemente una clase que herede de 'Template' y sobreescriba varios métodos, encapsulando la clase del motor de plantillas a usar (Smarty por ejemplo). No pongo el código ahora porque se me puede quedar inmenso el post.
Y así, trabajo de forma transparente independientemente de cómo sea la capa de la presentación y de qué formato escupa: HTML, PDF, XML... (aunque hay q preocuparse por implementar cada funcionalidad).
5. (y acabo ya!!) WorkData es aquella clase que encapsula los datos de la petición y de la respuesta. Además encapsula la sesión y el manejor de cookies. (este último está aún por implementar
)
Y creo que ya paro! menudo ladrillazo, lo siento señores
vitxete.