Bookmark and Share

Lee's 程序人生

HTML CSS Javascript XML AJAX ATLAS C# C++ 数据结构 软件工程 设计模式 asp.net Java 数字图象处理 Sql 数据库
  博客园  :: 首页  :: 新随笔  :: 联系 :: 管理

Zend Framework 与设计模式 (四) - strategy 策略模式

Posted on 2010-02-05 19:51  analyzer  阅读(471)  评论(0编辑  收藏  举报

在传统的面向过程语言中经常充斥着大量的 if/else 语句。这种情况不仅容易令逻辑变得混乱,而且修改麻烦。strategy 策略模式正是为了解决此类问题而诞生的。

 

当我们遇到一个问题,有多种解决的策略时,我们就可以用 strategy 模式。它的主要思想就是为所有策略类 subclasses 提供一个统一的固定的接口 interface ,例如一个父类 parent 。我们可以用这个接口定义各种所需的策略。

 

下面让我们看看 Zend_Application_Resource_Resource 是如何实现 strategy 的。

 

 

以下都是经过简化的源代码,首先是统一接口 : 

 

<?php
/**
 * bootstrap resources 资源统一接口
 */

interface Zend_Application_Resource_Resource
{
    // Constructor 初始化函数
    public function __construct($options = null);

    // 其它函数
    public function setBootstrap(Zend_Application_Bootstrap_Bootstrapper $bootstrap);
    public function getBootstrap();
    public function setOptions(array $options);
    public function getOptions();
 
    /**
     * Strategy 模式 : 统一的 init 方法
     * @return mixed
     */

    public function init();
}

 

接着是父类 Zend_Application_Resource_ResourceAbstract : 

 

<?php
/**
 * @see Zend_Application_Resource_Resource
 */

require_once 'Zend/Application/Resource/Resource.php';
 
/**
 * 资源虚拟父类
 * @uses Zend_Application_Resource_Resource
 */

abstract class Zend_Application_Resource_ResourceAbstract implementsZend_Application_Resource_Resource
{
    // 实现接口函数
    public function __construct($options = null)
    {
        // ......
    }

    public function setOptions(array $options)
    {
        //......
        return $this;
    }

    public function getOptions()
    {
        // ......
    }

    public function setBootstrap(Zend_Application_Bootstrap_Bootstrapper $bootstrap)
    {
        // ......
        return $this;
    }

    public function getBootstrap()
    {
        // ......
    }

    // ......

    // init()方法将在子类中实现
}

 

注意我们没有在父类中实现 init() 方法,而且因为父类被声明为 abstract 的关系,我们必须在其子类中实现 init() 函数,才可以正常使用 resource 资源。以下是 Layout 及 View 两个例子。

 

Zend_Application_Resource_Layout : 

 

<?php
/**
 * 配置 layout 资源类 : Zend_Application_Resource_Layout
 * @uses Zend_Application_Resource_ResourceAbstract
 */

class Zend_Application_Resource_Layout
    extends Zend_Application_Resource_ResourceAbstract
{
    // @var Zend_Layout
    protected $_layout;

    /**
     * 由 Zend_Application_Resource_Resource 定义
     * @return Zend_Layout
     */

    public function init()
    {
        $this->getBootstrap()->bootstrap('FrontController');
        return $this->getLayout();
    }

    /**
     * 获取 layout 对象
     * @return Zend_Layout
     */

    public function getLayout()
    {
        if (null === $this->_layout) {
            $this->_layout = Zend_Layout::startMvc($this->getOptions());
        }
        return $this->_layout;
    }
}

 

Zend_Application_Resource_View : 

 

<?php
/**
 * 配置 view 资源类 : Zend_Application_Resource_View
 * @uses Zend_Application_Resource_ResourceAbstract
 */

class Zend_Application_Resource_View
    extends Zend_Application_Resource_ResourceAbstract
{
    // @var Zend_View_Interface
    protected $_view;

    /**
     * 由 Zend_Application_Resource_Resource 定义
     * @return Zend_View
     */

    public function init()
    {
        $view = $this->getView();
        $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
        $viewRenderer->setView($view);
        Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
        return $view;
    }

    /**
     * 获取 view 对象
     * @return Zend_View
     */

    public function getView()
    {
        if (null === $this->_view) {
            $this->_view = new Zend_View($this->getOptions());
        }
        return $this->_view;
    }
}

 

而真正调用 init() 的则是 Zend_Application_Bootstrap_Bootstrap 类。它负责收集所有资源并执行其初始化函数 init() : 

 

<?php
/**
 * Zend_Application_Bootstrap_Bootstrap::_executeResource($resource)
 * 调用一个资源
 */

protected function _executeResource($resource)
{
    // ......

    if ($this->hasPluginResource($resource)) {
        // ......
        $plugin = $this->getPluginResource($resource);
        $return = $plugin->init();
        // ......
    }
}

 

这就是 Zend_Application_Bootstrap_Bootstrap 引用资源并初始化资源的解决方案。同时,我们还可以通过其通用接口 Zend_Application_Resource_ResourceAbstract ,很方便的实现自己的资源。

 

实际上 Zend Framework 大量使用了 strategy 策略模式,在 Zend_Controller_Action_Helper,Zend_View_Helper,Zend_Filter 等等中都可以见到它的身影。

转自:http://kbs.kimbs.cn/blog/list/post/15/title/strategy-pattern-in-Zend-Framework 

我要啦免费统计