`
wangwengcn
  • 浏览: 175553 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

6.代理模式(Proxy Pattern)

阅读更多

1.定义:

为其他对象提供一种代理以控制这个对象的访问。
代理模式也叫委托模式,它是一项基本设计技巧。许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了代理模式。

 

2.代理模式的三个角色定义:

  • Subject抽象主题角色:抽象主题类可以是抽象类,也可以是接口,是一个最普通的业务类型定义,无特殊要求。
  • RealSubject具体主题角色:也叫被委托角色、被代理角色。是业务逻辑的具体执行者。
  • Proxy代理主题角色:也叫委托类、代理类。它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后工作。(最简单的比如打印日志)

3.代理模式的使用场景:

想想现实世界中,打官司为什么一定要找个律师?因为你不想参与中间过程的是是非非,只要完成自己的答辩就成,其他的比如事前调查、时候追查都由律师来搞定。同理,在我们程序设计中也可是使用代理模式来将由一系列无关逻辑组合在一起的代码进行解耦合,比如业务代码中的日志代码就可以在代理中进行。Spring的AOP就是典型的动态代理应用。

 

4.代理模式的扩展一(普通代理):

普通代理,它的要求是客户端只能访问代理角色,而不能访问真实角色(真实角色在proxy构造方法中创建),我们只要修改一下上面的proxy类就可以了,请看代码:

 

package _6ProxyPattern;

/**
 * 定义一个会玩游戏的人的接口
 * 他必须先登录,然后开始玩游戏
 */
public interface IGamePlayer {

	public void login();
	
	public void play();
	
	public String getUserName();
}

 

package _6ProxyPattern;

import java.util.Date;

/**
 * 这是一个游戏玩家
 */
public class GamePlayer implements IGamePlayer {

	private String userName;
	
	public GamePlayer(String userName)
	{
		this.userName = userName;
	}
	
	@Override
	public void login() {
		System.out.println("玩家:"+userName+"登录了;时间:"+new Date().toString());
	}

	@Override
	public void play() {
		System.out.println("玩家:"+userName+"正在打怪");
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

}
 
package _6ProxyPattern;

/**
 * 我是一个游戏代练
 */
public class ProxyPlayer implements IGamePlayer {
	
	// 这是我要代练的账号
	private IGamePlayer gamePlayer;

	public ProxyPlayer(IGamePlayer gamePlayer)
	{
		this.gamePlayer = gamePlayer;
	}
	
	@Override
	public void login() {
		System.out.println("日志:"+getUserName()+"开始代练"+gamePlayer.getUserName()+"的游戏账号了");
		gamePlayer.login();
	}

	@Override
	public void play() {
		System.out.println("日志:"+getUserName()+"开始给"+gamePlayer.getUserName()+"的游戏账号打怪升级了");
		gamePlayer.play();
	}

	// 代练者也是有名字的
	@Override
	public String getUserName() {
		return "代练者-李四";
	}

}

 

5.代理模式的扩展二(强制代理):

现实中可能会有这样的场景:你去找一个明星帮忙,该明星告诉你他比较忙,要你先联系他的助理(代理),助理然后安排时间,明星才帮你做事情。也就是说你虽然找到了真实角色,真实角色却强制你去寻找代理。
强制代理在设计模式中比较另类,为什么这么说呢?一般的思维都是通过代理找到真实的角色,但是强制代理却要强制你必须通过真实角色查找到代理角色,否则你不能访问。
强制代理的概念就是要从真实角色查找到代理角色,不允许直接访问真实角色。高层模块只要调用getProxy就可以访问真实角色的所有方法。代理的管理已经由真实角色自己完成了。
请看代码:

package _6ProxyPattern.forced;

/**
 * 定义一个会玩游戏的人的接口
 * 他必须先登录,然后开始玩游戏
 */
public interface IGamePlayer {

	public void login();
	
	public void play();
	
	public String getUserName();
	
	public IGamePlayer getProxy();
}
 
package _6ProxyPattern.forced;

import java.util.Date;

/**
 * 这是一个游戏玩家
 */
public class GamePlayer implements IGamePlayer {

	private String userName;
	private IGamePlayer proxy;
	
	public GamePlayer(String userName)
	{
		this.userName = userName;
	}
	
	@Override
	public void login() {
		if(isProxy())
		{
			System.out.println("玩家:"+userName+"登录了;时间:"+new Date().toString());
		}else{
			System.out.println("请使用指定的代理");
		}
	}

	@Override
	public void play() {
		if(isProxy())
		{
			System.out.println("玩家:"+userName+"正在打怪");
		}else{
			System.out.println("请使用指定的代理");
		}
	}

	@Override
	public IGamePlayer getProxy() {
		this.proxy = new ProxyPlayer(this);
		return proxy;
	}
	
	private boolean isProxy()
	{
		if(proxy == null)
		{
			return false;
		}
		return true;
	}
	
	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}
}
 
package _6ProxyPattern.forced;

/**
 * 场景类,除了这种方式,别的方式调用将会提示你采用代理方式访问
 */
public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		IGamePlayer gamePlayer = new GamePlayer("张三");
		IGamePlayer proxyPlayer = gamePlayer.getProxy();
		proxyPlayer.login();
		proxyPlayer.play();
	}

}

 

6.代理模式的扩展三(虚拟代理):

虚拟代理很简单,在需要的时候才初始化真实角色对象,可以避免被代理对象较多而引起的初始化缓慢问题。
请看代码:

package _6ProxyPattern;

/**
 * 我是一个游戏代练
 */
public class VirualProxyPlayer implements IGamePlayer {
	
	// 这是我要代练的账号
	private IGamePlayer gamePlayer;

	@Override
	public void login() {
		if(gamePlayer == null)
		{
			gamePlayer = new GamePlayer("张三");
		}
		System.out.println("日志:"+getUserName()+"开始代练"+gamePlayer.getUserName()+"的游戏账号了");
		gamePlayer.login();
	}

	@Override
	public void play() {
		if(gamePlayer == null)
		{
			gamePlayer = new GamePlayer("张三");
		}
		System.out.println("日志:"+getUserName()+"开始给"+gamePlayer.getUserName()+"的游戏账号打怪升级了");
		gamePlayer.play();
	}

	// 代练者也是有名字的
	@Override
	public String getUserName() {
		return "代练者-李四";
	}

}

 

7.代理模式的扩展四(动态代理):

现在有个非常流行的名称叫做面向切面编程,也就是AOP(Aspect Oriented Programming),其核心就是采用了动态编程。
实现一般有两种方式,一种是基于JDK InvocationHandler接口 ,另一种是基于cglib的字节码增强技术

 

8.代理模式优点:

  • 职责清晰:真实的角色就是实际的业务逻辑,不用关心其他非本职责的事物,通过后期的代理完成一件事物
  • 高扩展性:具体主题角色是随时都会发生变化的,只要它实现了接口,甭管它如何变化,我们的代理类完全可以在不做任何修改的情况下使用
  • 代理类不仅仅是可以有自己的运算方法,通常情况下,代理的职责并不单一,它可以组合其他的真实角色,也可以实现自己的职责,比如上例中代理在play的同时,要进行收费。
分享到:
评论

相关推荐

    代理模式 Proxy Pattern

    ### 代理模式 Proxy Pattern #### 概念定义 代理模式是一种结构型设计模式,它允许程序员为某对象创建一个代理对象来控制对该对象的访问。简单来说,就是在不修改原始类的基础上,通过引入代理对象来扩展类的行为...

    C#设计模式_设计模式_C#_

    代理模式(Proxy Pattern) 行为型: 13. 模板方法(Template Method) 14. 命令模式(Command Pattern) 15. 迭代器模式(Iterator Pattern) 16. 观察者模式(Observer Pattern) 17. 解释器模式(Interpreter Pattern) 18....

    设计模式 之 “代理模式[Proxy Pattern]”

    **代理模式(Proxy Pattern)**是软件设计模式中的结构型模式之一,它在对象访问控制、增加额外功能或在客户端与目标对象之间提供一个中介等方面有广泛的应用。在代理模式中,代理类作为真实对象的代表,它持有真实...

    代理模式(Proxy Pattern)完整示例代码

    代理模式是一种设计模式,它允许我们为一个对象创建一个代理对象,这个代理对象可以在原对象进行某些操作之前或之后添加额外的功能。代理模式的核心在于,它提供了一种方式来间接访问或控制目标对象,增加了系统的...

    设计模式之代理模式proxy

    **设计模式之代理模式(Proxy Pattern)** 设计模式是软件工程中的一种最佳实践,它是在特定情境下解决常见问题的模板。代理模式是其中一种行为设计模式,它的核心思想是为一个对象提供一个替身或者代理,以控制对...

    设计模式代码——c#

    12. 代理模式(Proxy Pattern) 行为型 13. 模板方法(Template Method) 14. 命令模式(Command Pattern) 15. 迭代器模式(Iterator Pattern) 16. 观察者模式(Observer Pattern) 17. 解释器模式(Interpreter ...

    23种设计模式 (创建型,结构型,行为型)

    代理模式(Proxy Pattern) 13. 模板方法(Template Method) 14. 命令模式(Command Pattern) 15. 迭代器模式(Iterator Pattern) 行为型: 16. 观察者模式(Observer Pattern) 17. 解释器模式(Interpreter ...

    java 设计模式之代理模式(Proxy Pattern)实现代码及设计详解:动态代理模式、静态代理模式

    在这些模式中,代理模式(Proxy Pattern)是一种常用的结构型设计模式,它允许我们为一个对象创建一个代理,该代理对象在客户端和目标对象之间起到中介的作用,可以增加额外的功能或控制访问。 代理模式分为两种...

    Android设计模式之代理模式(Proxy Pattern)

    代理模式是设计模式的一种,它的主要目的是在不改变原有对象的基础上,为一个对象提供额外的功能或者控制对这个对象的访问。在Android开发中,代理模式的应用尤为常见,尤其在处理复杂的业务逻辑、网络请求、界面...

    Proxy Pattern 代理模式

    Proxy Pattern 代理模式 采用JAVA实现,可以下载看看。

    32种设计模式

    代理模式(Proxy Pattern) 13. 模板方法(Template Method) 14. 命令模式(Command Pattern) 15. 迭代器模式(Iterator Pattern) 行为型: 16. 观察者模式(Observer Pattern) 17. 解释器...

    c++-设计模式之代理模式(Proxy)

    代理模式(Proxy Pattern)是一种结构型设计模式,用于为其他对象提供一种代理以控制对这个对象的访问。代理模式通常用于保护、延迟加载、记录请求等场景,可以在不改变原有对象的情况下为其增加新的功能。 代理...

    JavaScript设计模式.pdf

    8. 代理模式(Proxy Pattern): 代理模式是控制对象的访问,包括推迟对其创建需要耗用大量计算资源的类的实例化。它的主要作用是控制对象的访问,提高系统的安全性和可扩展性。 9. 观察者模式(Observer Pattern)...

    Java24种设计模式,Java24种设计模式,24种设计模式,学会了这24种设计模式,可以打遍天下无敌手,设计模式非常重要

    2、代理模式PROXY PATTERN 3、单例模式SINGLETON PATTERN 4、多例模式MULTITION PATTERN 5、工厂方法模式FACTORY METHOD PATTERN 6、抽象工厂模式ABSTRACT FACTORY PATTERN 7、门面模式FACADE PATTERN 8、适配器...

    JAVA设计模式(创建模式 结构模式 行为模式)

    2. 代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问,可以用于远程代理、虚拟代理、保护代理等。 3. 桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地...

    C#23种设计模式【完整】.pdf

    12. 代理模式(Proxy Pattern):为其他对象提供一个代理,以控制对这个对象的访问。 13. 模板方法模式(Template Method):定义一个操作中的算法骨架,而将一些步骤延迟到子类中,实现了基类的算法可复用。 行为...

    C++设计模式基础教程.pdf

    6. 代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问。 7. 装饰者模式(Decorator Pattern):动态的给一个对象添加一些额外的职责。 8. 适配器模式(Adapter Pattern):将一个类的接口...

    C#23种开发模式实例

    5. 代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问。在C#中,可以利用虚方法、接口或System.Threading.Tasks.Task来实现。 6. 原型模式(Prototype Pattern):用原型实例指定创建对象...

    C++设计模式课件15_Proxy_代理模式.pdf

    代理模式(Proxy Pattern)是一种结构型设计模式,它在客户端与目标对象之间提供了一个代理对象。这个代理对象能够控制对目标对象的访问,并且可以添加额外的功能或操作。简而言之,代理模式的核心在于提供一个代理...

    java设计模式详解,java design pattern

    3. 代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问。 4. 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象。 5. 外观模式(Facade Pattern):为子系统中的一...

Global site tag (gtag.js) - Google Analytics