1

我正在启动一个基于 zend 框架的应用程序;此应用程序应该能够使用数据库以外的多个数据源;例如一个网络服务。

我一直在阅读如何构建我的模型以允许这种情况。我遇到了各种似乎为此提供解决方案的概念(DataMapper 模式、服务模式、适配器层等)。但是,我仍然对如何将所有这些组合成一个可重用和可扩展的代码库感到困惑。

我以前使用过 zend 框架,通常会使用 mysql 表。例如,如果我有一个用户表...我的模型中有一个用户类,它包含用户域的业务逻辑和一个扩展 Zend_Db_Table_Row_Abstract 的用户类,代表用户表中的一行。

如何最好地组织我的模型和代码库,以便我仍然可以调用 $users->fetchAll() 并获取用户对象的集合,而不管我的数据源是什么?

4

1 回答 1

4

它基本上和你以前做的一样工作,只是Zend_Db_Table_Gateway你使用 a而不是 a My_UserGateway_Whatever,例如首先创建一个接口:

interface UserGateway
{
    /**
     * @return array
     * @throws UserGatewayException
     */
    public function findAll();
}

我们不希望来自具体网关的异常出现在消费代码中,因此我们将 UserGatewayException 添加为全部:

 class UserGatewayException extends RuntimeException
 {}

然后添加一个实现该接口的类:

class My_UserGateway_Webservice implements UserGateway
{
    public function findAll()
    {
        try {
            // insert logic to fetch from the webservice
            return $userData;
        } catch (Exception $e) {
            throw new UserGatewayException($e->getMessage(), $e->getCode, $e);
        }
    }

    // … more code
}

同样,如果你想使用数据库源,你可以为 Zend_Db_* 类编写一个适配器,例如

class My_UserGateway_Database implements UserGateway
{
    private $tableDataGateway;

    public function __construct(Zend_Db_Table_Abstract $tableDataGateway)
    {
        $this->tableDataGateway = $tableDataGateway;
    }

    public function findAll()
    {
        try {
            return $this->tableDataGateway->select()->blah();
        } catch (Exception $e) {
            throw new UserGatewayException($e->getMessage(), $e->getCode, $e);
        }
    }

    // … more code
}

如果您需要另一个数据提供者,请确保他们实现了该接口,以便您可以依赖该findAll方法。使您的消费类依赖于接口,例如

class SomethingUsingUsers
{
    private $userGateway;

    public function __construct(UserGateway $userGateway)
    {
        $this->userGateway = $userGateway;
    }

    public function something()
    {
        try {
            $users = $this->userGateway->findAll();
            // do something with array of user data from gateway
        } catch (UserGatewayException $e) {
            // handle Exception
        }
    }

    // … more code
}

现在,当您创建时,SomethingUsingUsers您可以轻松地将一个或另一个网关注入到构造函数中,无论您使用哪个网关,您的代码都可以正常工作:

$foo = SomethingUsingUsers(
    new My_UserGateway_Database(
        new Zend_Db_Table('User')
    )
)

或者,对于 Web 服务:

$foo = SomethingUsingUsers(
    new My_UserGateway_Webservice(
        // any additional dependencies
    )
)
于 2012-10-26T11:04:42.197 回答