Java设计模式之代理模式(基础篇)

Java设计模式之代理模式

1 代理模式的定义

代理模式就是为其他对象提供一种代理以控制对这个对象的访问的模式。

2 代理模式的动机

在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。换言之,就是在一些情况下,一个人或者一个机构代表另一个人或机构采取行动。使用代理模式创建对象,让代理对象控制目标对象的访问(目标对象可以是远程对象、创建开销大的对象或需要安全控制的对象),并且可以在不改变目标对象的情况下添加一些额外的功能。

3 代理模式的结构

Java设计模式之代理模式(基础篇)_第1张图片


4 代理模式的角色

4.1 Subject角色

抽象主题角色,抽象主题类可以是抽象类,也可以是接口,是一个最普通的业务类型定义,无特殊要求。其声明了真是主题和代理主题的共同接口,这样一来任何可以使用真实主题的地方都可以使用代理主题。

4.2 RealSubject角色

具体主题角色,也叫做委托角色、被代理角色。是业务逻辑的具体执行者。

4.3 Proxy角色

代理主题角色,也叫做委托类、代理类。代理主题角色把所有抽象主题类定义的方法给具体主题角色实现,并且在具体主题角色处理完毕前后做预处理和善后工作(最简单的比如打印日志);代理主题角色内部含有对真实主题的引用,从而可以在任何时候操作真实主题对象;代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候都可以代替真实主题;代理主题角色控制对真实主题的引用,负责在需要的时候创建(或删除)真实主题对象。

5 代理模式的例子

5.1 Subject

package com.wchy.patterns.proxydemo.dao;

/**
 * 抽象主题,定义主要功能
 * @author wchy
 *
 */
public abstract class Subject 
{
	public abstract void operation();
}

5.2 RealSubject

package com.wchy.patterns.proxydemo.dao.impl;

import org.apache.log4j.Logger;

import com.wchy.patterns.proxydemo.dao.Subject;

/**
 * 具体主题
 * @author wchy
 *
 */
public class RealSubject extends Subject 
{
	private static final Logger LOGGER = Logger.getLogger(RealSubject.class);
	
	@Override
	public void operation() 
	{
		LOGGER.debug("Real subject operation.");
	}

}

5.3 ProxySubject

package com.wchy.patterns.proxydemo.proxy;

import org.apache.log4j.Logger;

import com.wchy.patterns.proxydemo.dao.Subject;

/**
 * 代理主题
 * @author wchy
 *
 */
public class ProxySubject extends Subject 
{
	private static final Logger LOGGER = Logger.getLogger(ProxySubject.class);
	
	Subject subject;
	
	public ProxySubject() 
	{
	}
	
	public Subject getSubject() 
	{
		return subject;
	}

	public void setSubject(Subject subject) 
	{
		this.subject = subject;
	}

	@Override
	public void operation() 
	{
		preOperation();
		subject.operation();
		nextOperation();
	}
	
	private void preOperation() 
	{
		LOGGER.debug("Preprocessing operations.");
	}
	
	private void nextOperation() 
	{
		LOGGER.debug("The aftermath of Operation.");
	}
}

5.4 Client

package com.wchy.patterns.proxydemo.client;

import com.wchy.patterns.proxydemo.dao.Subject;
import com.wchy.patterns.proxydemo.dao.impl.RealSubject;
import com.wchy.patterns.proxydemo.proxy.ProxySubject;

import junit.framework.TestCase;

/**
 * 客户
 * @author wchy
 *
 */
public class DemoTest extends TestCase 
{
	public void testcase01() 
	{
		Subject subject = new RealSubject();
		ProxySubject proxySubject = new ProxySubject();
		proxySubject.setSubject(subject);
		proxySubject.operation();
	}
}

6 代理的实际应用

Spring的AOP:典型的动态代理;Achilles:远程代理;Windows的快捷方式;生活中的秘书、律师等。

7 代理模式的形式

7.1 远程代理(Remote Proxy)

可以隐藏一个对象存在于不同地址空间的事实。也使得客户端可以访问在远程主机上的对象,远程机器可能具有更好的计算机性能与处理速度,可以快速响应并处理客户端的请求。

7.2 虚拟代理(Virtual Proxy)

允许内存开销较大的对象在需要的时候创建。只有我们真正需要这个对象的时候才创建。

7.3 写入式复制代理(Copy-On-Write Proxy)

用来控制对象的复制,方法是延迟对象的复制,直到客户真正需要为止,是虚拟代理的一种变体。

7.4 保护代理(Protected (Access)Proxy)

为不同的客户提供不同级别的目标对象访问权限。

7.5 缓存代理(Cache Proxy)

为开销大的运算结果提供暂时存储,它允许多个客户端共享结果,以减少计算或网络延迟。

7.6 防火墙代理(Firewall Proxy)

控制网络资源的访问,保护主题免于恶意客户的侵害。

7.7 同步代理(Synchronization Proxy)

在多线程的情况下为主题提供安全的访问。

7.8 智能引用代理(Smart ReferenceProxy)

当一个对象被引用是,提供一些额外的操作,比如将对此对象调用的次数记录下来等。

7.9 复杂隐藏代理(Complexity HidingProxy)

用来隐藏一个类的复杂集合的复杂度,并进行访问控制。有时候也称为外观代理(Facade Proxy),这不难理解。复杂隐藏代理和外观模式是不一样的,因为代理控制访问,而外观只是提供另一组接口。


你可能感兴趣的:(设计模式)