proxy模式:
1.使用中间层,所有外部访问都必须经过中间代理层,经过权限检查后才能对内部访问。
2.某个客户端不能直接操作到某个对象,但又必须和那个对象有所互动,即对于开销很大的对象,不能立即创建时,先创建一个proxy顶替。
uml图分析:
proxy继承于待访问服务端的抽象类。因为proxy作为服务端的stub,必须有服务端的所有方法,但此处的实现仅仅为概念上的实现,具体的实现在别处。
proxy发消息(调用实现方法)给服务端的实现类,即上述所说的方法具体的实现类,以完成client的请求。
proxy类和服务端具体实现类都必须实现同一个接口或抽象类。
Jive论坛的proxy模式实现:
//定义权限类
public class ForumPermissions implements Cacheable {
public static final int READ = 0;
public static final int SYSTEM_ADMIN = 1;
public static final int FORUM_ADMIN = 2;
public static final int USER_ADMIN = 3;
public static final int GROUP_ADMIN = 4;
public static final int MODERATE_THREADS = 5;
public static final int CREATE_THREAD = 6;
public static final int CREATE_MESSAGE = 7;
public static final int MODERATE_MESSAGES = 8;
.....
public boolean isSystemOrForumAdmin() {
return (values[FORUM_ADMIN] || values[SYSTEM_ADMIN]);
}
.....
}
//
定义proxy层,因为该proxy必须作为外部访问内部的一个存根(stub)因此必须实现Forum抽象类,且一切外部对Forum的访问都必须经过该proxy层
//
public class ForumProxy implements Forum {
private ForumPermissions permissions;
private Forum forum;
this.authorization = authorization;
public ForumProxy(Forum forum, Authorization authorization,
ForumPermissions permissions) //构造函数,通过构造函数的初始化加载代访问的论坛forum,访问权限authorization,访问权限的设定permissions,即代访问的内部对象和已拥有的权限来访问内部//
{
this.forum = forum;
this.authorization = authorization;
this.permissions = permissions;
}
.....
public void setName(String name) throws UnauthorizedException, //定义概念上的服务端方法,具体实现不在此处
ForumAlreadyExistsException
{
//对访问forum作权限检查,只有是系统或论坛管理者才可以修改名称//
if (permissions.isSystemOrForumAdmin()) {
forum.setName(name); //概念上的服务端方法调用具体实现的服务端方法
}
else {
throw new UnauthorizedException();
}
}
...
}
//定义待访问论坛的真正方法实现//
public class DbForum implements Forum, Cacheable {
....
public void setName(String name) throws ForumAlreadyExistsException {
....
this.name = name;
//这里真正将新名称保存到数据库中
saveToDb();
....
}
....
}
//定义client
public class client{
public static void main(String agrs[])
{
protected DbForum forum;
protected ForumPermissions permissions;
protected Authorization authorization;
String forumname=new String("king");
ForumProxy visit=new ForumProxy(forum,permissions,authorization );
visit.setName(forumname);
}
}
//以factory模式来重写proxy//
public class ForumFactoryProxy extends ForumFactory {
protected ForumFactory factory;
protected Authorization authorization;
protected ForumPermissions permissions;
public ForumFactoryProxy(Authorization authorization, ForumFactory factory,
ForumPermissions permissions)
{
this.factory = factory;
this.authorization = authorization;
this.permissions = permissions;
}
public Forum createForum(String name, String description)
throws UnauthorizedException, ForumAlreadyExistsException
{
//只有系统管理者才可以创建forum
if (permissions.get(ForumPermissions.SYSTEM_ADMIN)) {
Forum newForum = factory.createForum(name, description);
return new ForumProxy(newForum, authorization, permissions); //返回ForumProxy,供外部访问
}
else {
throw new UnauthorizedException();
}
}
方法createForum返回的也是ForumProxy,Proxy就象一道墙,其它程序只能和Proxy交互操作。
注意到这里有两个Proxy:ForumProxy和ForumFactoryProxy。代表两个不同的职责:使用Forum和创建Forum。