PHP面向对象之前端控制器模式

/*

前端控制器的主要组成部分及功能如下:
1、入口文件类controller;(对这个系统的调用都是从这个文件开始的,也相当于一个控制中心,对所有相关的类进行调用)
2、应用程序配置信息类applicationhelper;(用于获取应用程序所需的配置信息)
3、命令类解释器commandresolver;(根据用户请求调用相应的命令类)
4、命令类command;(调用用户请求信息类和业务逻辑,还可以调用视图文件)

整个系统的调用步骤大概就是:
1、获取程序所需的配置信息
2、获取命令类
3、执行命令类

前端控制器与命令模式对比,在我看来二者基本没什么区别,原理大致相同。前端控制器的代码及注解如下:

*/

namespace woo\controller;

//入口文件类
class Controller {
    private $applicationHelper;
    private function __construct ();

    static function run(){
        $instance = new Controller();
        $instance->init();
        $instance->handleRequest();
    }

    function init(){                    //获取程序所需的配置信息
        $applicationHelper = ApplicationHelper::instance();
        $applicationHelper->init();
    }

    function handleRequest(){            //获取并执行命令类
        $request = new \woo\controller\Request();
        $cmd_r = new \woo\command\CommandResolver();
        $cmd = $cmd_r->getCommand($request);
        $cmd->execute($request);
    }
}

//获取应用程序配置信息
class ApplicationHelper {
    private static $instance;
    private $config = "/tmp/data/woo_options.xml";        //配置信息保存的文件

    private function __construct (){}

    static function instance(){
        if(!self::$instance){
            selff::$instance = new self();
        }
        return self::$instance;
    }

    function init(){
        $dsn = \woo\base\ApplicatonRegistry::getDSN();
        if(!is_null($dsn)){
            return;
        }
        $this->getOptions();
    }

    private function getOptions(){
        $this->ensure(file_exists($this->config),"conld not find options file");
        $options = SimpleXml_load_file($this->config);
        print get_class($options);
        $dsn = (string)$options->dsn;
        $this->ensure($dsn,"No DSN found");
        \woo\base\ApplicationRegistry::setDSN($dsn);        //配置信息将被缓存到一个注册表类中
        //设置其他值

    }

    private function ensure($expr,$message){
        if(!$expr){
            throw new \woo\base\AppException($message);
        }
    }

}

//用户请求信息类
class Request {
    private $properties;
    private $feedback =array();
    function __construct(){
        $this->init();
        \woo\base\RequestRegistry::setRequest($this);
    }

    function init(){
        if(isset($_SERVER[‘REQUEST_METHOD‘])){
            $this->properties = $_REQUEST;
            return;
        }
        foreach($_SERVER[‘argv‘] as $arg){
            if(Strpos($arg,‘=‘)){
                list($key,$val) = explode("=",$arg);
                $this->setProperty($key,$val);
            }
        }
    }

    function getProperty($key){
        if(isset($this->properties[$key]){
            return $this->properties[$key];
        }
    }

    function setProperty($key,$val){
        $this->properties[$key] = $val;
    }

    function addFeedback($msg){
        array_push($this->feedback,$msg);
    }

    function getFeedback(){
        return $this->feedback;
    }
    function getFeedbackString($separator="\n"){
        return implode($separator,$this->feedback);
    }

}

namespace woo\command;

//命令解释器
class CommandResolver{
    private static $base_cmd;
    private Static $default_cmd;

    function __construct (){
        if(!self::$base_cmd){
            //命令类的基类,这个主要将使用反射来检查找到的命令类是否是继承了它
            self::$base_cmd = new \ReflectionClass("\woo\command\Command");
            self::$default_cmd = new DefaultCommand();    //默认的命令类,当找不到相应的命令类时将调用它
        }
    }

    //获取命令类
    function getCommand(\woo\controller\Request $request){
        $cmd = $request->getProperty(‘cmd‘);
        $sep = DIRECTORY_SEPARATOR;            //代表"/"
        if(!$cmd){
            return self::$default_cmd;
        }
        $cmd = str_replace(array(‘.‘,$sep),"",$cmd);
        $filepath = "woo{$sep}command{$sep}{$cmd}.php";    //命令类的文件路径
        $classname = "woo\\command\\{$cmd}";            //类名
        if(file_exists($filepath)){
            @require_once("$filepath");
            if(class_exists($classname)){
                $cmd_class = new ReflectionClass($classname);
                if($cmd_class->isSubClassOf(self::$base_cmd)){
                    return $cmd_class->newInstance();            //实例化命令类
                } else {
                    $request->addFeedback("command ‘$cmd‘ is not a Command");
                }
            }
        }
        $request->addFeedback("command ‘$cmd‘ not found");
        return clone self::$default_cmd;
    }
}

//命令类
abstract  class Command{
    final function __construct(){}
    function execute(\woo\controller\Request $request){
        $this->doExecute($request);
    }
    abstract function doExecute(\woo\controller\Request $request);
}

class DefaultCommand extends Command{
    function doExecute(\woo\controller\Request $request){
        $request->addFeedback("Welcome to Woo");
        include("woo/view/main.php");
    }
}

//客户端
require("woo/controller/Controller.php");
\woo\controller\Controller::run();
时间: 2024-10-29 19:05:38

PHP面向对象之前端控制器模式的相关文章

【设计模式】前端控制器模式

前端控制器模式(Front Controller Pattern)是用来提供一个集中的请求处理机制,所有的请求都将由一个单一的处理程序处理.该处理程序可以做认证/授权/记录日志,或者跟踪请求,然后把请求传给相应的处理程序.以下是这种设计模式的实体. 前端控制器(Front Controller) - 处理应用程序所有类型请求的单个处理程序,应用程序可以是基于 web 的应用程序,也可以是基于桌面的应用程序. 调度器(Dispatcher) - 前端控制器可能使用一个调度器对象来调度请求到相应的具

Java前端控制器模式~

前端控制器设计模式用于提供集中式请求处理机制,以便所有请求将由单个处理程序处理.此处理程序可以执行请求的身份验证/授权/记录或跟踪,然后将请求传递到相应的处理程序. 以下是这种类型的设计模式的实体. 前端控制器 - 用于处理应用程序(基于Web或基于桌面)的各种请求的单个处理程序. 分发器 - 前端控制器可以使用可以将请求分派到相应的特定处理器的分派器对象. 视图 - 视图是进行请求的对象. 实现实例 在这个实现实例中,将创建一个FrontController和Dispatcher作为前台控制器

前端控制器

原文地址: http://www.cnblogs.com/firstdream/archive/2012/02/09/2344160.html 前端控制器一 4年以前,当我还在一种叫ASP的东西上工作的时候,我整天为两个问题头疼不已:一是如何将分散的页面控制整合起来.解释型的服务器端脚本,每个页面都有 接收和处理请求的能力.这样以每个页面作为独立的单元来处理请求让人感觉粒度太小,分散又不爽.二是如何减少重复代码.脚本语言里处理重复代码的灵丹妙药 是include.每个页面里都可以include

前端控制器DispatcherServlet 详解

DispatcherServlet 是前端控制器设计模式的实现,提供 Spring Web MVC 的集中访问点,而且负责职责的分派,而且与 Spring IoC 容器无缝集成,从而可以获得 Spring 的所有好处 DispatcherServlet 主要用作职责调度工作,本身主要用于控制流程,主要职责如下: 1.文件上传解析,如果请求类型是 multipart 将通过 MultipartResolver 进行文件上传解析: 2.通过 HandlerMapping,将请求映射到处理器(返回一个

PHP面向对象之页面控制器

<?php /* 页面控制器模式:按我的理解就是将业务逻辑和视图分离开来(通常最简便的写法是php和html代码是混合在一个文件里面的), 即一个业务逻辑文件对应一个视图文件. 代码示例即注解如下: */ //页面控制器模式 namespace woo\controller; //业务逻辑文件 (文件名AddVenue.php) abstract class PageController { //基类 private $request; function __construct (){ $req

Magento路由分发过程解析(一):在前端控制器中获取路由对象(转)

Magento的路由系统,需要考虑到两个抽象层. 1,首先你需要了解,可能会有无数多个路由对象负责处理路由逻辑,最后只有一个路由对象能够获取并处理该请求.默认情况下,Magento拥有四个路由对象. 2,在这四种路由对象内,又有一系列不同的规则用于匹配url地址到相应的控制器方法.这些规则非常相似,只有一些细微的差别. 路由匹配迭代过程 Magneto的路由开始于前端控制器对象的Mage_Core_Controller_Varien_Front::dispatch()方法,在如下循环中,选择合适

面向对象之简单工厂模式

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Interface { class InterfaceTest { static void Main(string[] args) { #region 测试Cat,Monkey,Bear类 introduction test; for (int i = 1; i<=3; i++) { switch (i)

前端开发模式

现在很多前端开发的小伙伴对前端开发模式不是很了解,现在我写一些自己的学习心得和大家共享,希望有所收获! 首先第一个开发模式:工厂模式: 工厂模式顾名思义即是通过一个工厂去制造出很多相似的产品出来,就比如类似的汽车,火车,飞机等这些相似的产品,在流水线上制造出来,这样可以节省开发的时间,提高开发开发效率: function createPerson(name,age,job){ var o = new Object(); o.name = name; o.age = age; o.job = jo

springmvc 前端控制器,映射器,适配器,视图解析器

1.前端控制器DispatcherServlet的配置,在web.xml进行配置即可跟servlet的配置方式相同 1)contextConfigLocation配置sprimgmvc加载的配置文件(配置处理器映射器,适配器等等)如果不配置contextConfigLocation,默认加载的是/WEB-INF/servlet名称-servlet.xml(springmvc-servlet.xml) 2) 第一种:*.action,访问以.action结尾 由DispatcherServlet进