开发可维护的RPC系统

Jos*_*son 13 javascript ajax rpc zend-framework json-rpc

我正在开发一个Web应用程序,它将广泛使用AJAX技术进行客户端/服务器通信......特别是JSON-RPC.Zend Framework正在服务器端使用,它提供了一个很好的JSON-RPC服务器,我想使用它.

我的目标是构建一个可维护的系统,将大量服务器端功能暴露给客户端(javascript),而不会产生不必要的代码重复.我已经看过很多关于如何使用ZF的JSON-RPC服务器的博客文章和教程(见这里这里),但它们似乎都面向暴露一个小型的公共可用API.代码重复很常见,例如一篇博文有以下暴露方法:

public static function setTitle($bookId, $title) {
    $book = new Nickel_Model_Book($bookId);
    $book->setTitle($title);
    $book->update();
    return true;
}
Run Code Online (Sandbox Code Playgroud)

我不喜欢有两种setTitle方法的事实.如果一个方法签名发生变化,另一个必须保持同步...如果你的API很广泛,似乎是一个可维护性的噩梦.在我看来应该有一个Book类,有一种setTitle方法.

我最初的想法是为@export我想要暴露的方法/类添加一个docblock注释.当我决定公开setTitle方法时,我只是添加注释而不是新方法.

我看到的一个潜在问题涉及对象持久性.在服务器端,setTitle设置对象的title属性是有意义的......但是在update()调用之前不会将其保留在数据库中.客户端,调用setTitle应立即影响数据库.一种可能的解决方案是修改所有访问器,使得它们采用可选的第二个参数,表示修改应立即更新数据库:

function setTitle($title, $persist = false) {
    $this->title = $title;

    if ($persist) $this->update();
}
Run Code Online (Sandbox Code Playgroud)

某种代理类可以确保$persist为所有客户端RPC调用设置标志.

另一个问题是PHP对象的序列化.在服务器端,进行OO风格的$book->setTitle("foo")调用book.setTitle(1234, "foo")是有意义的,但由于缺乏状态,客户端是有意义的(其中1234是本书的ID).我的解决方案是让上述代理类负责以某种方式book.setTitle(1234, "foo")变成:

$book = new Book();
$book->load(1234);
return $book->setTitle($title);
Run Code Online (Sandbox Code Playgroud)

我觉得这个问题必须先解决或讨论过......但我在网上找不到很多资源.这看起来像是一个理智的解决方案吗?

JCM*_*JCM 3

您正在寻找的称为“服务层”

它们的实体应该是纯粹的数据容器(除非您使用 Active Record),您应该只公开您的服务层,而这又会访问它们的实体及其各自的方法。

“您的 Book 类是一个域模型,您现在应该创建您的服务层”

您的服务等级将是这样的:

class BookService extends Service {

    //...

    public function changeBookTitle( $title, Book $book )
    {
        //verify if the $title is correct and valid
        $book->setTitle( $title );
        $this->methodToGetThePersistenceManager()->save( $book );

        //fire events, create a result object, etc...
    }
}
Run Code Online (Sandbox Code Playgroud)