`

代理模式

阅读更多

饮料售卖机,需要有人监视它,如果饮料卖完了,需要往里面放饮料。

对饮料售卖机进行监视,通过把饮料售卖机对象传到监视器对象中以获取饮料售卖机的库存量以及当前状态。

 

饮料售卖机上进行监视,还是需要有人跑到售卖机前(很不方便)。

如果要远程监视饮料售卖机,我们可以通过饮料售卖机的代理,无需修改我们的代码。

代理假装它是真正的对象,但是其实一切的动作是它利用网络和真正的对象沟通。

 

代理模式:为另一个对象提供一个替身,以控制对这个对象的访问。

代理控制访问的方式:

远程代理控制访问远程对象

虚拟代理控制访问创建开销大的资源

保护代理基于权限控制对资源的访问

 

财务系统中,财务报表需要增加权限控制,普通用户无权限查看财务报表,管理员可以。

使用代理模式:创建财务报表的代理对象(代理对象包含真实的财务报表对象),用户通过查看代理对象就可以增加权限控制,无需修改代码。

package com.ez.impl;

import com.ez.FinancialStatements;
/**
 * 代理财务报表
 * 管理员才可以检查财务报表。
 * @author 窗外赏雪(EZ编程网)
 */
public class Test {
	public static void main(String[] args) {
		FinancialStatements realFinancialStatements=new RealFinancialStatements();
		boolean isAdmin=true;
		FinancialStatements fs=new ProxyFinancialStatements(realFinancialStatements, isAdmin);
		fs.check();
		isAdmin=false;
		fs=new ProxyFinancialStatements(realFinancialStatements, isAdmin);
		fs.check();
	}
}

 

 

package com.ez;
/**
 * 通过实现同一接口,代理能在任何财务系统出现的地方取代它。
 * @author 窗外赏雪(EZ编程网)
 */
public interface FinancialStatements {
	void check();
}

 

 

package com.ez.impl;

import com.ez.FinancialStatements;
/**
 * 真正做事的对象,它是被proxy代理和控制访问的对象。
 * @author 窗外赏雪(EZ编程网)
 */
public class RealFinancialStatements implements FinancialStatements{

	@Override
	public void check() {
		System.out.println("====欢迎查看年度财务报表====");
		System.out.print("总支出:$99999");
		System.out.println("总收入:$100000");
		System.out.println("盈利:$1");
		System.out.println("===========================");
	}

}

 

package com.ez.impl;

import com.ez.FinancialStatements;
/**
 * 客户和真正财务系统的交互都必须通过它。
 * 因为代理和真正财务系统实现相同的接口,所以任何用到财务系统的地方,都可以用该代理取代。
 * 代理还可以控制对这个对象的访问。has-a关系。
 * @author 窗外赏雪(EZ编程网)
 */
public class ProxyFinancialStatements implements FinancialStatements{
	private FinancialStatements realFinancialStatements;
	private boolean isAdmin;
	
	public ProxyFinancialStatements(FinancialStatements realFinancialStatements,boolean isAdmin) {
		this.realFinancialStatements=realFinancialStatements;
		this.isAdmin=isAdmin;
	}
	
	@Override
	public void check() {
		if(isAdmin){
			realFinancialStatements.check();
		}else{
			System.out.println("sorry no permission");
		}
	}

}

使用Java API的代理

Java在java.lang.reflect包中有自己的代理支持,利用这个包可以在运行时动态地创建一个代理类,实现一个或者多个接口并将方法的调用转发到你所指定的类。

因为实际的代理类是在运行时创建的,所以我们称这个为:动态代理。

 

因为Java已经为你创建Proxy类,不能像以前一样把控制访问的代码放在Proxy类中,控制访问的代码需要放在InvocationHandler中。

InvocationHandler的工作是,响应代理的任何调用,你可以把InvocationHandler想象成是代理收到方法调用后,请求做实际工作的对象。

 

代理模式,就是为一个对象找个替身,控制该对象的访问。

Java帮我们创建了代理对象,把响应代理的任何调用的业务逻辑抽离出来,单独放到InvocationHandler的实现类中。

这样可以让开发把精力更多的放在有价值的业务实现上面。

 

之前的财务系统代理模式,使用动态代理实现如下:

1、创建InvocationHandler

InvocationHandler实现了代理的行为,正如你将看到,Java负责创建真实代理类和对象。我们只需要提供在方法调用时知道做什么的handler。

2、写代码创建动态代理

需要写代码产生代理类,并实例化它。

3、利用适当的代理包装任何财务系统对象。

package com.ez.impl;

import java.lang.reflect.Proxy;
import com.ez.FinancialStatements;

/**
 * 代理财务报表 管理员才可以检查财务报表。
 * @author 窗外赏雪(EZ编程网)
 */
public class Test {
	/**
	 * 动态创建Proxy类并实例化Proxy对象
	 * 我们创建一个代理,将它的方法调用转发给InvocationHandler。
	 * @param realFinancialStatements
	 * @return
	 */
	private static FinancialStatements getProxyFinancialStatements(FinancialStatements realFinancialStatements) {
		return (FinancialStatements) Proxy.newProxyInstance(
				realFinancialStatements.getClass().getClassLoader(),
				realFinancialStatements.getClass().getInterfaces(),
				new PermissionInvocationHandler(realFinancialStatements, true));
	}

	public static void main(String[] args) {
		FinancialStatements realFinancialStatements=new RealFinancialStatements();
		FinancialStatements proxyFinancialStatements = getProxyFinancialStatements(realFinancialStatements);
		proxyFinancialStatements.check();
	}
}

 

package com.ez;
/**
 * 通过实现同一接口,代理能在任何财务系统出现的地方取代它。
 * @author 窗外赏雪(EZ编程网)
 */
public interface FinancialStatements {
	void check();
}

 

package com.ez.impl;

import com.ez.FinancialStatements;
/**
 * 真正做事的对象,它是被proxy代理和控制访问的对象。
 * @author 窗外赏雪(EZ编程网)
 */
public class RealFinancialStatements implements FinancialStatements{

	@Override
	public void check() {
		System.out.println("====欢迎查看年度财务报表====");
		System.out.print("总支出:$99999");
		System.out.println("总收入:$100000");
		System.out.println("盈利:$1");
		System.out.println("===========================");
	}

}

 

package com.ez.impl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import com.ez.FinancialStatements;
/**
 * InvocationHandler实现了代理的行为,正如你将看到,Java负责创建真实代理类和对象。
 * 我们只需要提供在方法调用时知道做什么的handler。
 * Java帮我们创建了代理对象,把控制访问的业务逻辑抽离出来,单独放到InvocationHandler的实现类中。
 * 这样可以让开发把精力更多的放在有价值的业务实现上面。
 * @author 窗外赏雪(EZ编程网)
 */
public class PermissionInvocationHandler implements InvocationHandler{

	private FinancialStatements realFinancialStatements;
	private boolean isAdmin;
	
	public PermissionInvocationHandler(FinancialStatements realFinancialStatements,boolean isAdmin) {
		this.realFinancialStatements=realFinancialStatements;
		this.isAdmin=isAdmin;
	}
	
	/**
	 * 每次proxy的方法被调用,就会导致proxy调用此方法。
	 * method就是proxy被调用的方法,args就是方法的参数。
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		if(isAdmin){
			method.invoke(realFinancialStatements, args);
		}else{
			System.out.print("sorry no permission");
		}
		return null;
	}

}

 

分享到:
评论

相关推荐

    代理模式的使用示例程序

    代理模式是一种设计模式,它在软件工程中扮演着重要的角色,允许我们为其他对象提供一个替代接口,以控制对原始对象的访问。这种模式的主要目的是为了增加灵活性、安全性或者在不修改原有对象的情况下,增强或扩展其...

    JAVA设计模式之代理模式实例

    代理模式是设计模式的一种,它提供了一种对目标对象进行增强或者控制访问的方式。在本实例中,我们将深入探讨Java中的代理模式及其应用。 代理模式的核心思想是为一个对象创建一个代理对象,这个代理对象在客户端和...

    设计模式之代理模式Proxy

    代理模式是设计模式中的一种结构型模式,它在对象交互中起到了中介的作用,允许通过代理对象来控制对原对象的访问。代理模式的核心思想是为一个对象提供一个替身,以便增加新的功能或者控制对原对象的访问。这种模式...

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

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

    android使用signalr代理模式和非代理模式

    SignalR提供了两种主要的工作模式:代理模式和非代理模式。这两种模式在实现上有所不同,各自具有优缺点,适用于不同的场景。 **1. 代理模式(Proxy Mode)** 在代理模式下,SignalR为每个Hub(服务端的业务逻辑...

    设计模式-代理模式

    代理模式是一种常用的设计模式,它在软件开发中扮演着重要的角色,特别是在iOS平台的应用程序设计中。代理模式的核心思想是为一个对象提供一个替身或代理,以控制对这个对象的访问。这种模式允许我们通过代理来间接...

    java中的三种代理模式

    在Java编程中,代理模式是一种常用的面向对象设计模式,它允许我们为一个对象提供一个代理以控制对该对象的访问。代理模式通常用于增加额外的功能,如日志、权限检查等,或者为了创建虚拟代理以提高性能。以下是Java...

    JAVA设计模式(代理模式)

    **Java设计模式——代理模式详解** 代理模式是软件设计模式中的一个重要组成部分,它在Java编程中扮演着举足轻重的角色。代理模式的核心思想是为一个对象提供一个替身,这个替身即代理对象,代理对象可以控制对原...

    代理模式小例子

    代理模式是一种设计模式,它在软件工程中扮演着重要的角色,允许我们为其他对象提供一个替代接口,以控制对原对象的访问。这种模式的主要目的是为了增加灵活性、安全性或者为对象提供额外的功能,同时保持客户端代码...

    设计模式之代理模式proxy

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

    设计模式实现——代理模式

    **设计模式实现——代理模式** 在软件工程中,设计模式是一种通用可重用的解决方案,它描述了在特定上下文中经常出现的问题以及该问题的解决方案。代理模式是设计模式的一种,它提供了一种对目标对象的间接访问方式...

    结构型模式之代理模式(Proxy)

    代理模式是一种设计模式,属于结构型模式之一,其主要目的是为其他对象提供一个代理,以控制对该对象的访问。在实际应用中,代理模式能够帮助我们实现如下的功能: 1. 远程代理:代理对象可以代表一个位于远程系统...

    Java设计模式-代理模式例子

    在这个“Java设计模式-代理模式例子”中,我们将深入探讨代理模式的概念、实现方式以及它在实际开发中的应用。 代理模式的核心思想是为一个对象提供一个替身,这个替身即代理对象,代理对象控制对原对象的访问。在...

    android设计模式之代理模式

    代理模式在软件设计中是一种常用的设计模式,尤其在Android开发中,它可以帮助我们实现复杂的控制逻辑,隔离复杂性,以及提供额外的功能。在Android上下文中,代理模式常常用于数据加载、权限控制、事件处理等方面。...

    设计模式C++学习之代理模式(Proxy)

    代理模式是一种设计模式,它是结构型模式之一,主要用于在客户端和目标对象之间建立一个代理对象,以便控制对目标对象的访问。在C++中,代理模式可以用来为其他对象提供一种代理以控制对这个对象的访问,或者增加...

    Java代理模式Java动态代理

    ### Java代理模式与Java动态代理详解 #### 一、代理模式概述 代理模式是一种软件设计模式,它在客户端和目标对象之间提供了一种间接层。这种模式的主要目的是控制客户端对目标对象的访问,并且可以在不修改原有...

    设计模式--代理模式

    代理模式是一种常用的设计模式,它在软件开发中扮演着重要角色,允许我们通过一个代理类来控制对原对象的访问。在《设计模式:可复用面向对象软件的基础》(通常称为GoF设计模式)中,代理模式被定义为“为其他对象...

    代理模式 C++实现

    代理模式(Proxy) 定义: 为其他对象提供一种代理以控制对这个对象的访问 结构: 由三部分组成 1.RealSubject(真实对象): 真正会调用到的对象 2.Proxy(代理对象): 代理真实对象的地方 3.Subject(共同点): 代理对象...

    cas代理模式代码示例

    在IT行业中,代理模式是一种常见的设计模式,它允许我们在不修改原有对象的基础上,为对象添加新的功能或控制访问。在本示例中,我们将重点讨论如何在Java环境下使用代理模式来实现代理逻辑,特别是在CAS(Central ...

Global site tag (gtag.js) - Google Analytics