Proxy模式的功能有很多,比如远程代理,用来给远程对象提供一个本地代表;虚代理,用来为创建开大开销的对象提供缓冲,等等。在Jive中使用的是保护代理,为被保护的对象提供权限控制。
我们都知道在一个论坛中,权限的控制是必须的,否则论坛就很可能会被搞得一团糟。Jive中引入Proxy对象,Authorization接口以及权限描叙属类来提供对论坛的保护。
以ForumFactory为例,一个额外的ForumFactoryProxy来处理权限认证的工作,它为某一个ForumFactory提供了一个代理,保证只有授权的用户才能够存取ForumFactory的某些操作。实际上ForumFactory在这儿不仅仅只是一个生成Forum的类的,它更像是一个Forum的管理类。提供了添加,删除,枚举等等一系列的功能,而有些功能不是什么样的人都可以使用的,因而引入了另外的一个代理类来处理权限的问题。
当然,代理类需要继承ForumFactory,以使方法签名一致:
ForumFactoryProxy extends ForumFactory
在它的构造方法中,就提供了一个ForumFactory对象,这是需要被代理的对象;一个Authorization对象,提供用户信息;还有一个ForumPermissions,提供认证信息:
public ForumFactoryProxy(ForumFactory factory, Authorization authorization,
ForumPermissions permissions)
{
this.factory = factory;
this.authorization = authorization;
this.permissions = permissions;
}
一般的代理过程都是这样的,在访问某个方法之前,必须接受权限的检查,以createForum为例:
public Forum createForum(String name, String description)
throws UnauthorizedException, ForumAlreadyExistsException
{
if (permissions.get(ForumPermissions.SYSTEM_ADMIN)) {
Forum newForum = factory.createForum(name, description);
return new ForumProxy(newForum, authorization, permissions);
}
else {
throw new UnauthorizedException();
}
}
下面给出这个模式的类图:
图3:Proxy模式的类图
这个模式的实现基本上和GOF中所给出的实现一致。在Jive中,几乎所有的接口,Forum,ForumMessage,ForumThread等等,都会有一个相应的Proxy对象来进行权限控制。而在创建具体的对象的时候,都是用相应的Proxy对象来代替原有的对象返回的。例如在ForumFactory的getInstance()方法中需要返回一个Forum的时候,Jive是这样做的:
public static ForumFactory getInstance(Authorization authorization) {
......
ForumFactoryProxy proxy = new ForumFactoryProxy(factory,authorization, factory.getPermissions(authorization));
return proxy;
}
因而,所有被创建的对象实际上都是Proxy对象,抽象工厂保证了没有权限验证的对象根本不会客户所得到,它们只会在Proxy的内部扮演角色,而永远不会被外部对象所存取,这样,就从根本上保证了论坛的安全。