设计模式【代理模式】

首先我们先了解代理,代理是指一个人或者一个机构代表另一个人或者机构采取行动。代理模式给某一个对象提供一个代理对象,并由代理对象控制对象控制对原对象的引用。

代理模式一般涉及三个角色:

Subject:抽象角色,声明真实对象和代理对象的共同接口;

    Proxy:代理角色,代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象鱼与真

实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。简言之,代理角色是业务逻辑的具体执行者。

    RealSubject:真实角色,代理角色所代表的真实对象,即我们最终要引用的对象。

案例场景:

客户Client,通过手机代理商MobileProxy(Proxy)购买(获取)一部手机(Mobile),而真实手机提供商是手机工厂MobileFactory(RealSubject)。

【转载使用,请注明出处:http://blog.csdn.net/mahoking

演示程序:

/**
 * 物品商品对象
 * @author Mahc
 */
public class Mobile {
	public void call() {
		System.out.println("Mobile[合格]可以打电话!");
	}
}

/**
 * RealSubject
 * @author Mahc
*/
public class MobileFactory implements Factory {

@Override
	public Mobile produce() {
		return new Mobile();
	}
}

/**
 * Subject 抽象对象
 * @author Mahc
 */
public interface Factory {
	public Mobile produce();
}

/**
 * Proxy对象
 * @author Mahc
 */
public class MobileProxy implements Factory {

	private MobileFactory factory;

	/**MobileProxy 构造函数*/
	protected MobileProxy(MobileFactory mobileFactory) {
		this.factory = mobileFactory;
	}

	@Override
	public Mobile produce() {
		return factory.produce();
	}
}

/**
 * 模拟客户对象
 * @author Mahc
 */
public class Client {

	public static void main(String[] args) {
		//真实的Mobile生产商
		MobileFactory mobileFactory = new MobileFactory();
		MobileProxy mobileProxy = new MobileProxy(mobileFactory);
		//使用MobileProxy对象的produce()方法,生产Mobile
		Mobile mobile = mobileProxy.produce();
		mobile.call();
	}
}

在此我们已经初步了解了设计模式中的代理模式,下面我们进一步了解代理模式中静态代理与动态代理的区别。

静态代理(Static Proxy):真实对象和代理对象有共同的接口, 代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的方法。

动态代理(Dynamic Proxy):真实对象和抽象对象有共同的接口,代理对象角色通过Java的反射机制

(java.lang.reflect.Method.newProxyIntance())获得,同时代理对象(为java.lang.reflect.InvocationHandler的子类通

过invoke())调用真实对象相同的方法。

所以从综上所示可知,第一个演示案例为静态代理模式。下面我们提供动态代理模式的案例。本例所涉及的新的知识点需要读者和本人在平时不断补充与积累。例如反射机制的思想与相关的Java API,如果学习深入会发现这方面的学习会触及AOP(面向切面编程)。

动态代理案例:

/**
 * 获取动态代理对象的类
 * @author Mahc
 *
 */
public class ProxyHandler implements InvocationHandler{

	private Object object;

	public ProxyHandler(Object object) {
		this.object = object;
	}

	/**
	 * 生成代理对象的静态方法
	 * @param realObject
	 * @return
	 */
	public static Object  getProxyIntance(Object realObject){

		Class<?> classType = realObject.getClass();
        return Proxy.newProxyInstance(classType.getClassLoader(),
                classType.getInterfaces(),  new ProxyHandler(realObject));
	}

	/**
	 * proxy 代理对象
	 * method 调用的方法
	 * args 方法的参数
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		if("produce".equalsIgnoreCase(method.getName())){
			System.out.println("执行了Mobile.call()");
		}
		Object resultObj = method.invoke(object, args);
//		System.out.println(resultObj.getClass());
		return resultObj;
	}

}

public class Client {

	public static void main(String[] args) {

		MobileFactory mobileFactory = new MobileFactory();
		Factory factory = (Factory) ProxyHandler.getProxyIntance(mobileFactory);
		Mobile mobile = factory.produce();
		mobile.call();
	}
}

下面我们来对比两种代理模式的优缺点。

静态代理:

优点:

1、对象直观,静态代理是实实在在的存在的,我们创建编写。

2、在编译期加入,提前就指定好使用对象,所以效率高。

缺点:

1、 代理对象与真实对象关联性高,所以需要代理多个真实对象时,需要大量的代理类。

2、 在编译期加入关联对象,系统的灵活性差。

动态代理:

优点:

1、一个动态代理类可以简单解决创建多个静态代理的麻烦。

2、调用目标代码时,会在方法“运行时”动态的加入,调用灵活。

缺点:

1、系统灵活了,但是相比而言,效率降低了,比静态代理慢一点。

2、动态代理比静态代理在代码的可读性上差了一点,不太容易理解。

3、JDK动态代理只能对实现了接口的类进行代理。(这个问题下面会介绍)

静态代理VS动态代理,各自有各的独特之处,均不可代替,在项目中到底使用哪种代理模式,需要根据自身的需要来定。下面我们来解释上面遗留的问题,以上我们介绍的这种动态代理叫做jdk proxy即原生的jdk代理,它其实也不是完美的,它只能代理实现了接口的类如【MobileFactory implements
Factory】,不能对类本身实现代理,要完成对类本身实现代理,需要用到另外一个开源的类库cglib【CGLIB(Code Generation Library)】,还有待继续我们平时不断学习与研究。

【转载使用,请注明出处:http://blog.csdn.net/mahoking

时间: 2024-10-15 06:41:06

设计模式【代理模式】的相关文章

设计模式 - 代理模式(proxy pattern) 未使用代理模式 详解

代理模式(proxy pattern) 未使用代理模式 详解 本文地址: http://blog.csdn.net/caroline_wendy 部分代码参考: http://blog.csdn.net/caroline_wendy/article/details/37698747 如果需要监控(monitor)类的某些状态, 则需要编写一个监控类, 并同过监控类进行监控. 但仅仅局限于本地, 如果需要远程监控, 则需要使用代理模式(proxy pattern). 具体方法: 1. 类中需要提供

设计模式——代理模式

概念 代理模式(Proxy),为其他对象提供一种代理以控制对象的访问. 模式结构 一个是真正的你要访问的对象(目标类),一个是代理对象,真正对象与代理对象实现同一个接口,先访问代理类再 访问真正要访问的对象. 代理模式UML图 代码实战 <span style="font-family:KaiTi_GB2312;font-size:18px;"> //代理模式 class  Proxy : IGiveGift                   //让"代理&qu

23种设计模式----------代理模式(二)

(上一篇)23种设计模式----------代理模式(一) 之前说了基本的代理模式和普通代理模式.接下来开始看下强制代理模式和虚拟代理模式 三,强制代理模式: 一般的代理模式都是通过代理类找到被代理的对象,从而调用被代理类中的方法(即完成被代理类中的任务). 而,强制代理模式则是先找到被代理类自己去完成事情,然后被代理类又将该做的事情转交到代理类中,让代理类来完成. 假如:你有事求助于某位名人. 你告诉名人说有事想请他帮忙,然后他说最近一段时间比较忙,要不你找我的经纪人来办吧. (本来找名人办事

23种设计模式----------代理模式(三) 之 动态代理模式

(上一篇)种设计模式----------代理模式(二) 当然代理模式中,用的最广泛的,用的最多的是  动态代理模式. 动态代理:就是实现阶段不用关系代理是哪个,而在运行阶段指定具体哪个代理. 抽象接口的类图如下: --图来自设计模式之禅 所以动态代理模式要有一个InvocationHandler接口 和 GamePlayerIH实现类.其中 InvocationHandler是JD提供的动态代理接口,对被代理类的方法进行代理. 代码实现如下 抽象主题类或者接口: 1 package com.ye

23种设计模式----------代理模式(一)

代理模式也叫委托模式. 代理模式定义:对其他对象提供一种代理从而控制对这个对象的访问.就是,代理类 代理 被代理类,来执行被代理类里的方法. 一般情况下,代理模式化有三个角色. 1,抽象的主题类(或者接口) IGamePlayer 2,代理类. 3,被代理类. 下面以游戏玩家代理为例. 一,先来看下最基本的代理模式. 代码如下: 主题接口: 1 package com.yemaozi.proxy.base; 2 3 //游戏玩家主题接口 4 public interface IGamePlaye

5.大话设计模式-代理模式

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignModel { public class Proxy:IAction { ZQZ zzz = null; public Proxy(ZQZ mm) { zzz = mm; } public void SendFlower() { zzz

设计模式----代理模式(Proxy)

为还有一个对象提供一个替身或占位符以控制对这个对象的訪问. 代理模式的组成: 主题接口(Subject):提取真正主题与代理的公共方法,让使用真正主题的地方也能用代理取代. 真正主题(RealSubject):真正处理请求的类. 代理(Proxy):真正主题的代理类,请求方通过调用代理对象间接调用真正主题. 代理模式的简单样例: (主题接口类)Subject.java package xu.neng.Proxy; public interface Subject { public void re

一起学java设计模式--代理模式(结构型模式)

代理模式 应用软件所提供的桌面快捷方式是快速启动应用程序的代理,桌面快捷方式一般使用一张小图片来表示(Picture),通过调用快捷方式的run()方法将调用应用软件(Application)的run()方法.使用代理模式模拟该过程,绘制类图并编程实现. package ProxyPattern; interface Software { void run(); } class Application implements Software { public void run() { Syste

设计模式-代理模式(Go语言描述)

大家好, 我是大帅哥,由于最近又变帅了, 所以我决定由我的代理人小帅哥来写这篇博客,不过内容可以放心,还是由我来完成,小帅哥的活就是将我的内容替我发出来罢了. &_& 还是进入正题吧, 今天这篇博客我们继续来学习设计模式, 在学习了上面几个设计模式之后大家有没有发现设计模式其实很简单, 难道地方是何时选用合适的模式, 这也是设计模式最重要的地方, 不能我们学会的设计模式就可以乱用. 明白就好-- 下面我们就开始介绍一个新的设计模式-代理模式. 模式定义 什么是代码模式? 其实文章刚开始的段

Java设计模式-代理模式之动态代理(附源码分析)

Java设计模式-代理模式之动态代理(附源码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的区别就是:动态代理是在运行时刻动态的创建出代理类及其对象.上篇中的静态代理是在编译的时候就确定了代理类具体类型,如果有多个类需要代理,那么就得创建多个.还有一点,如果Subject中新增了一个方法,那么对应的实现接口的类中也要相应的实习该方法,不符合设计模式原则. 动态代理的做法:在运行时刻,可以动态创建出一个实现了多个接口的代理类.每个代理类的对象都会关联一个表示内部处理