为什么需要适配器
在讲解ice servant的章节中说到,服务端要想真正把服务提供给客户,就要把ice servant和ice object联系起来,负责建立这种联系的东西就叫做ice适配器(adapter)。ice adapter和ice proxy从本质上讲是一样的,都是建立一个中间层,把客户和最终需求之间进行解耦,只不过称呼不一样。
作用
每个对象适配器都有一个或更多Ice服务员,负责服务Ice 对象;同时还有一个或更多传输端点。如果对象适配器拥有的传输端点不止一个,所有向该适配器注册了的Ice服务员可以在任何一个端点(endpoint)上响应到来的请求。换句话说,如果对象适配器有多个传输端点,这些端点代表的是通往同一组对象的不同通信路径(例如,通过不同的传输机制)。
通信框架图
实现原理
每个对象适配器都维护有一个叫作活动servant映射表(active servantmap)的数据结构。 活动servant 映射表(简称为ASM)是一个查找表,用于把对象标识映射到servant:在C++ 里,查找值是智能指针,指向对应的servant 在内存中的位置;在Java 里,查找值是指向servant 的Java 引用。
当客户把操作调用发给服务器时,请求的目标是特定的传输端点。传输端点隐含地标识了请求所针对的对象适配器(因为同一个端点只能绑定到一个对象适配器)。
客户端发送请求的Ice代理含有对应的Ice对象的标识,客户端run time会在发送请求的中带上这个Ice对象标识。Ice适配器继而使用这个对象标识,在它的ASM 中查找正确的servant,把发送请求分派给它进行服务。
适配器带来的好处
使用适配器作为服务端提供服务的最小单位,使得服务端在为ice object提供服务的时候,把ice object和ice servant之间进行了解耦。也就是说当客户端的请求接口不变,但是业务需求变化的情况下,服务端只需要通过ice adapter重新建立ice object和ice servant的关系就可以实现该功能。
举个列子:有一家专门做交通工具租赁的公司,原来提供给客户旅行的方式只有汽车,现在有一部分是飞机。你现在另一个地方新开了一家分店,专门用来进行飞机旅行的,用分布式系统中的说法就是部署在新服务器上的servant不一样。用代码表示如下:
//ice对象
interface Traffic
{
//给客户提供旅行
void travel();
};
//原有的ice servant
class OldTrafficI
{
//原有的交通工具都是跑的
void run();
}
adapter(Traffic,OldTrafficI);
//新加的ice servant
class NewTrafficI
{
//新加的交通工具都是飞的
void fly();
}
adapter(Traffic,NewTrafficI);
适配器和通信器的关系
每个对象适配器都只属于一个通信器,但一个通信器可以有多个对象适配器。