- 论坛徽章:
- 0
|
一.概念:
代理模式(Proxy)是一种对象结构性模式,别名surrogate。代理模式的意图是提供一种代理以控制对这个对象的访问。
二.何种情况下使用代理模式
以下是两类使用代理模式的实例:
1.授权机制 不同级别的用户对同一对象拥有不同的访问权利,如Jive论坛系统中,就使用Proxy进行授权机制控制,访问论坛有两种人:注册用户和游客(未注册用户),Jive中就通过类似ForumProxy这样的代理来控制这两种用户对论坛的访问权限.
2.某个客户端不能直接操作到某个对象,但又必须和那个对象有所互动.
举例两个具体情况:
(1)如果那个对象是一个是很大的图片,需要花费很长时间才能显示出来,那么当这个图片包含在文档中时,使用编辑器或浏览器打开这个文档,打开文档必须很迅速,不能等待大图片处理完成,这时需要做个图片Proxy来代替真正的图片.
(2)如果那个对象在Internet的某个远端服务器上,直接操作这个对象因为网络速度原因可能比较慢,那我们可以先用Proxy来代替那个对象.
按照使用目的来分类:可分为以下几种:
远程代理(remote proxy)为一个对象在不同的地址空间提供局部代表。
保护代理(Protection proxy)控制对原始对象的访问。
虚拟代理(Virtual proxy)根据需要创建开销很大的对象。
智能指引(Smart Reference)取代简单的指针,它在访问对象时执行一些附加操作。包括对指向对象的引用计数,当第一次引用一个持久对象时,将它载入内存。
三.结构:
![]()
抽象主题角色(Subject):声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题的地方都可以使用代理主题。
代理主题(Proxy)角色:代理主题角色内部含有对真是主题的引用,从而可以在任何时候操作真实主题对象;代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候都可以替代真实主体;控制真实主题的应用,负责在需要的时候创建真实主题对象(和删除真实主题对象);代理角色通常在将客户端调用传递给真实的主题之前或之后,都要执行某个操作,而不是单纯的将调用传递给真实主题对象。
真实主题角色(RealSubject)角色:定义了代理角色所代表的真实对象。
四.代码示例:
1.简单实现演示:
using System;
// "Subject"
abstract class Subject
{
//
Methods
abstract public void Request();
}
// "RealSubject"
class RealSubject : Subject
{
//
Methods
override public void Request()
{
Console.WriteLine("Called RealSubject.Request()");
}
}
// "Proxy"
class Proxy : Subject
{
//
Fields
RealSubject realSubject;
//
Methods
override public void Request()
{
// Uses "lazy initialization"
if( realSubject == null )
realSubject = new RealSubject();
preRequest();
realSubject.Request();
postRequest();
}
public void preRequest()
{
Console.WriteLine("PreRequest."); }
public void postRequest()
{
Console.WriteLine("PostRequest."); }
}
/**////
/// Client test
///
public class Client
{
public static void Main( string[] args
)
{
// Create proxy and request a service
Proxy p = new Proxy();
p.Request();
}
}
2.论坛系统的用户有多种类型:注册普通用户 论坛管理者
系统管理者 游客,注册普通用户才能发言;论坛管理者可以管理他被授权的论坛;系统管理者可以管理所有事务等,这些权限划分和管理是使用Proxy完成的.
Forum是Jive的核心接口,在Forum中陈列了有关论坛操作的主要行为,如论坛名称 论坛描述的获取和修改,帖子发表删除编辑等.
public class ForumPermissions implements
Cacheable {
/**
* Permission to read object.
在ForumPermissions中定义了各种级别权限的用户:
*/
public static final int READ = 0;
/**
* Permission to administer the entire
sytem.
*/
public static final int SYSTEM_ADMIN = 1;
/**
* Permission to administer a particular
forum.
*/
public static final int FORUM_ADMIN = 2;
/**
* Permission to administer a particular
user.
*/
public static final int USER_ADMIN = 3;
/**
* Permission to administer a particular
group.
*/
public static final int GROUP_ADMIN = 4;
/**
* Permission to moderate threads.
*/
public static final int MODERATE_THREADS =
5;
/**
* Permission to create a new thread.
*/
public static final int CREATE_THREAD = 6;
/**
* Permission to create a new message.
*/
public static final int CREATE_MESSAGE = 7;
/**
* Permission to moderate messages.
*/
public static final int MODERATE_MESSAGES = 8;
.....
public boolean isSystemOrForumAdmin() {
return
(values[FORUM_ADMIN] || values[SYSTEM_ADMIN]);
}
}
//论坛代理类
public class ForumProxy implements Forum {
private ForumPermissions permissions;
private Forum forum;
this.authorization = authorization;
public ForumProxy(Forum forum, Authorization authorization,
ForumPermissions permissions)
{
this.forum = forum;
this.authorization = authorization;
this.permissions = permissions;
}
.....
public void setName(String name) throws UnauthorizedException,
ForumAlreadyExistsException
{
//只有是系统或论坛管理者才可以修改名称
if
(permissions.isSystemOrForumAdmin()) {
forum.setName(name);
}
else {
throw new
UnauthorizedException();
}
}
}
而DbForum才是接口Forum的真正实现,以修改论坛名称为例:
public class DbForum implements Forum,
Cacheable {
public void setName(String name) throws ForumAlreadyExistsException
{
this.name =
name;
//这里真正将新名称保存到数据库中
saveToDb();
}
}
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/17663/showart_197669.html |
|