`

设计模式:代理模式

 
阅读更多

 

 

1,抽象角色

package com.langsin.proxy;

//抽象角色
public abstract class Subject {
	abstract public void request();
}

 

2,真实角色

package com.langsin.proxy;

//真实角色
public class RealSubject extends Subject{
	public RealSubject() {
	}
	public void request(){
		System.out.println("from real subject!");
	}
}

 

3,代理角色

package com.langsin.proxy;

//代理角色
public class ProxySubject extends Subject{
	private RealSubject realSubject = new RealSubject();

	public ProxySubject() {
	}
	
	public void request(){
		preRequest();
		if(realSubject == null){
			realSubject = new RealSubject();
		}
		realSubject.request();
		postRequest();
	}
	
	public void preRequest(){
		System.out.println("pre request!");
	}
	
	public void postRequest(){
		System.out.println("post request!");
	}
	
	public static void main(String[] args) {
		Subject subject = new ProxySubject();
		subject.request();
	}
}

 

测试类:

package com.langsin.proxy;

public class Client {
	public static void main(String[] args) {
		Subject subject = new ProxySubject();
		subject.request();
	}
}

 

打印结果

pre request!
from real subject!
post request!

 

理解: 真实角色就好像一个具体做事的局长,如批文等。而代理角色就好像其秘书,外部将具体的任务交给秘书,由秘书再转交给局长来执行。秘书可以局长执行任务前后附加一些功能。这就是代理角色。

 

 

 

 

 

 

 

 

package com.langsin.dynamicproxy;

//抽象角色(上一例是抽象类)现在改为接口。

public interface Subject {
	public void request();
}

 

package com.langsin.dynamicproxy;

//真实角色
public class RealSubject implements Subject{
	public RealSubject(){
	}
	public void request() {
		System.out.println("from real subject!");
	}
}

 

package com.langsin.dynamicproxy;

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

//代理处理器
/*
 * 该代理类内部属性sub为Object类,实际使用时通过该类的构造函数DynamicSubject(Object obj)对其赋值;
 * 此外,在该类还实现了invoke方法,该方法中的method.invoke(sub,args);
 * 其实就是调用被代理对象的将要被执行的方法,方法参数sub是实际的被代理对象,
 * args为执行被代理对象相应操作所需的参数。
 * 通过动态代理类,我们可以在调用之前或之后执行一些相关操作
 */
public class DynamicSubject implements InvocationHandler{
	private Object sub;

	public DynamicSubject() {
	}

	public DynamicSubject(Object obj) {
		this.sub = obj;
	}

	//此方法由JAVA动态调用
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("before invoke!"+method);
		method.invoke(sub, args);
		System.out.println("after invoke!"+method);
		return null;
	}
}

 

package com.langsin.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

//客户端
public class Clent {
	public static void main(String[] args) {
		RealSubject rs = new RealSubject(); //在这里指定被代理类
		InvocationHandler ds = new DynamicSubject(rs);
		//一次性生成代理,以下内容可以运行时动态改变,这就是动态代理的优势
		Subject subject = (Subject) Proxy.newProxyInstance(rs.getClass().getClassLoader(),
					rs.getClass().getInterfaces(), ds);
		subject.request();
	}
}

 打印结果为:

before invoke!public abstract void com.langsin.dynamicproxy.Subject.request()
from real subject!
after invoke!public abstract void com.langsin.dynamicproxy.Subject.request()

 

 

 

 

 

 

 

package com.langsin.vectorproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Vector;

public class VectorProxy implements InvocationHandler{

	private Object proxyobj;
	
	public VectorProxy(Object obj) {
		proxyobj = obj;
	}
	
	public static Object factory(Object obj){
		Class<?> cls = obj.getClass();
		return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), new VectorProxy(obj));
	}
	
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("before !"+method);
		if(args != null){
			for (int i = 0; i < args.length; i++) {
				System.out.println(args[i]);
			}
		}
		Object object = method.invoke(proxyobj, args);
		System.out.println("after !"+method);
		return object;
	}
	
	public static void main(String[] args) {
		List<String> v = (List<String>)factory(new Vector<String>(10));
		v.add("new");
		v.add("york");
		System.out.println(v.hashCode());
		v.remove(0);
		System.out.println(v);
	}
}


  

打印结果:

before !public abstract boolean java.util.List.add(java.lang.Object)
new
after !public abstract boolean java.util.List.add(java.lang.Object)
before !public abstract boolean java.util.List.add(java.lang.Object)
york
after !public abstract boolean java.util.List.add(java.lang.Object)
before !public native int java.lang.Object.hashCode()
after !public native int java.lang.Object.hashCode()
7093744
before !public abstract java.lang.Object java.util.List.remove(int)
0
after !public abstract java.lang.Object java.util.List.remove(int)
before !public java.lang.String java.lang.Object.toString()
after !public java.lang.String java.lang.Object.toString()
[york]

 

 

 

 

 

package com.langsin.foo;

public interface Foo
{
    void doAction();
}

 

 

package com.langsin.foo;

public class FooImpl implements Foo
{
    public FooImpl()
    {
    }

    public void doAction()
    {
        System.out.println("in FooImp1.doAction()");
    }
}

 

 

package com.langsin.foo;

public class FooImpl2 implements Foo
{
    public FooImpl2()
    {
    }

    public void doAction()
    {
        System.out.println("in FooImp2.doAction()");
    }

}

 

package com.langsin.foo;

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

public class CommonInvocationHandler implements InvocationHandler {

	// 动态执行对象,需要回调的对象
	private Object target;

	// 支持构造子注射
	public CommonInvocationHandler() {

	}

	// 支持构造子注射
	public CommonInvocationHandler(Object target) {
		setTarget(target);
	}

	// 采用setter方法注射
	public void setTarget(Object target) {
		this.target = target;
	}

	/**
	 * 调用proxy中指定的方法method,并传入参数列表args
	 * @param proxy 代理类的类型,例如定义对应method的代理接口
	 * @param method被代理的方法
	 * @param args调用被代理方法的参数
	 */
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		return method.invoke(target, args);
	}

}

 

package com.langsin.foo;

import java.lang.reflect.Proxy;

public class Demo
{
	public static void main(String[] args){
		// 1.通用的动态代理实现
		CommonInvocationHandler handler = new CommonInvocationHandler();
		Foo f;
		// 2.接口实现1
		handler.setTarget(new FooImpl());
		// 方法参数说明:代理类、代理类实现的接口列表、代理类的处理器
		// 关联代理类、代理类中接口方法、处理器,当代理类中接口方法被调用时,会自动分发到处理器的invoke方法
		// 如果代理类没有实现指定接口列表,会抛出非法参数异常
		f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[] { Foo.class },handler);
		f.doAction();
		// 3.接口实现2
		handler.setTarget(new FooImpl2());
		f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[] { Foo.class },handler);
		f.doAction();
	}
}

  

 

分享到:
评论

相关推荐

    设计模式:可复用面向对象软件的基础.zip

    设计模式是软件工程中的一种重要概念,它代表了在特定情境下解决常见问题的最佳实践。这些模式经过时间的考验,被广泛应用于各种面向对象的软件开发中,以提高代码的可读性、可维护性和可复用性。本教程旨在深入讲解...

    设计模式:可复用面向对象软件的基础(非扫描版+高清)

    设计模式分为三类:创建型模式(如单例模式、工厂方法模式)、结构型模式(如代理模式、装饰器模式)和行为型模式(如观察者模式、策略模式)。每种模式都有其特定的用途和适用场景。 4. **具体设计模式详解** - ...

    《设计模式:可复用面向对象软件的基础》英文版

    如适配器模式(Adapter)、桥接模式(Bridge)、组合模式(Composite)、装饰者模式(Decorator)、外观模式(Facade)、享元模式(Flyweight)和代理模式(Proxy)等。 - **行为型模式**:关注于对象间的职责分配,...

    设计模式:可复用面向对象软件的基础--详细书签版

     “[设计模式]在实用环境下特别有用,因为它分类描述了一组设计良好,表达清楚的面向对象软件设计模式。整个设计模式领域还很新,本书的四位作者也许已占据了这个领域造诣最深的专家中的半数,因而他们定义模式的方法...

    《设计模式:可复用面向对象软件的基础》学习并理解 23 种设计模式

    《设计模式:可复用面向对象软件的基础》一书介绍了23种经典的设计模式,这些模式大致可以分为三大类: 1. **创建型模式**:专注于对象的创建机制,确保系统在合适的时机创建正确的对象。 - **单例模式**...

    设计模式:可复用的面向对象软件的基础

    - 代理模式:用于控制对游戏资源的访问,如延迟加载或异步加载资源。 通过应用设计模式,游戏引擎开发者能够更好地实现软件的复用性、可维护性,以及更好的软件质量。学习和掌握设计模式,对于开发高质量、高性能、...

    设计模式:可复用面向对象软件设计基础(附源码)

    2. **结构型模式**:如适配器模式、装饰器模式、代理模式、桥接模式、组合模式、外观模式和享元模式。这些模式关注如何将类或对象以某种方式组合起来,以实现新的功能或改善现有结构。 3. **行为型模式**:包括责任...

    1.《设计模式:可复用面向对象软件的基础(完整书签)》

    总的来说,《设计模式:可复用面向对象软件的基础》是一本深入理解和应用面向对象设计的必备书籍,它不仅介绍了23种核心设计模式,还提供了大量实例和解释,帮助读者将理论知识转化为实际的编程技巧。通过对这本书的...

    iOS开发中的几种设计模式介绍

    本文将深入探讨几种在iOS开发中常用的设计模式:代理模式、观察者模式、MVC模式、单例模式、策略模式以及工厂模式。 1. **代理模式**: 代理模式在iOS开发中广泛应用,主要用于对象间通信。例如,UITableView的...

    设计模式_基于C#的工程化实现及扩展_源码

    《设计模式:基于C#的工程化实现及扩展》是一份深入探讨软件设计模式的宝贵资源,它提供了C#语言下的具体实现与扩展,旨在帮助开发者提升代码的可读性、可维护性和可复用性。这个压缩包包含了多个源码文件,分别命名...

    C#面向对象设计模式纵横谈(25):设计模式总结

    12. 代理模式:代理模式为其他对象提供一种代理以控制对这个对象的访问,可以实现远程代理、虚拟代理和保护代理。 13. 模板方法模式:模板方法模式定义一个操作中的算法骨架,而将一些步骤延迟到子类中,使得子类...

    设计模式:简单工厂、方法工厂、抽象工厂、单例、原型、委派、模板、代理、策略

    8. **代理**:代理模式为其他对象提供一种代理以控制对这个对象的访问。它可以在不影响客户端的情况下,增强或限制原始对象的功能。 9. **策略**:策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。...

    设计模式可复用面向对象软件的基础 源码

    在《设计模式:可复用面向对象软件的基础》一书中,作者Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides(通常被称为GoF,Gang of Four)详细阐述了23种经典的设计模式。这些模式分为三类:创建型模式、...

    设计模式:可服用面向对象软件的基础

    7. 代理模式:为其他对象提供一种代理以控制对这个对象的访问。 三、行为型模式(Behavioral Patterns) 1. 责任链模式:将请求沿着处理者链传递,直到有对象处理它为止。 2. 命令模式:将请求封装为一个对象,...

    设计模式教材pdf 中文版

    - 代理模式:为其他对象提供一种代理以控制对这个对象的访问。 - 模板方法模式:在抽象类中定义一个操作中的算法骨架,而将一些步骤延迟到子类中。 3. 行为型设计模式: - 责任链模式:避免将处理逻辑硬编码到...

    23种设计模式(C++).pdf

    - Proxy模式:为其他对象提供一种代理以控制对这个对象的访问。 行为型模式包括: - Template模式:在一个方法中定义一个算法的骨架,将一些步骤延迟到子类中。Template方法使得子类可以在不改变算法结构的情况下,...

    9. 结构性设计模式小结1

    1. 代理模式: 代理模式是一种行为型和结构性模式,它为一个对象提供一个代理以控制对该对象的访问。代理对象在客户端和目标对象之间起到中介的作用,可以添加额外的功能,比如日志记录、安全控制、缓存等非核心...

    设计模式-代理模式

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

Global site tag (gtag.js) - Google Analytics