interface/class 的 Nonmutating 和 Idempotent

Nonmutating 操作

 

    有一些操作,例如上面代码中的getTime操作,这个操作不会修改所操作的对象的值。它们在概念上等效于C plus plus的const 成员函数。你可以如下的指出这样的操作:

 

        interface Clock
        {
                nonmutating TimeOfDay getTime();
                void setTime(TimeOfDay time);
        };

    nonmutating关键字指出了getTime操作不会修改它所操作的对象的状态。这样使用有两个原因:

 

  • 语言映射可以关于操作行为的附加知识的好处。例如:对于C plus plus来说,nonmutating操作映射到const成员函数。
  • 当得知一个操作不会修改对象的状态,则允许Ice运行时更积极的进行错误恢复。特别的,Ice会保证操作调用的最多一次语义。

    对于普通的操作,Ice运行时对于如何处理错误是保守的。例如,如果一个客户端发送一个操作调用到服务器,然后丢失了连接,对于客户端的 Ice运行时来说,没有办法知道调用是否成功。这就意味着,运行时不能通过尝试重新连接和再次发送请求来恢复错误,因为这可能第二次引发操作以及违背了最多一次语义。运行时没有选择,只能把错误报告给应用。对于nonmutating操作,换句话说,客户端的运行时可以尝试再次连接和安全的二次送出失败的请求。如果第二次发送能够到达服务器,那么万事OK。只有第二次再次失败,错误才会报告给应用(错误重试的次数可以在Ice的配置文件中配置)。

 

    Idempotent操作

 

    我们可以更进一步去修改上面的Clock接口的定义,从而可以让setTime操作是idempotent的:

 

        interface Clock
        {
                nonmutating TimeOfDay getTime();
                idempotent void setTime(TimeOfDay time);
        };

    对某一个操作进行两次成功的操作,其结果都一样,就像只调用了一次一样,那么这个操作就是idempotent操作。例如,x = 1; 是一个idempotent操作因为不管执行了一次还是两次,x的值都是1。换句话说,x += 1;就不是一个idempotent操作,因为它执行了两次后,结果不同了。

 

    idempotent关键字指出了一个操作能够安全的执行多次。同nonmutating操作一样,Ice运行时使用idempotent来达到更积极地错误恢复。

 

    一个操作只能是nonmutating或idempotent,不能两个都是。(nonmutating隐含了idempotent)


你可能感兴趣的:(interface/class 的 Nonmutating 和 Idempotent)