代理模式

 

原文链接:https://blog.csdn.net/leisure_life/article/details/68491528

代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。 
 

代理模式分为静态代理、动态代理。 
 

静态代理是由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。 
 

动态代理是在实现阶段不用关心代理类,而在运行阶段才指定哪一个对象。

 

就静态代理举个栗子

 

有两个人,有很多money的张三和24K纯屌丝李四,他们做着做同样的事情——惹上了官司和吃饭,张三就雇用专业的律师打官司,饭自己吃;李四雇不起律师,只好自己上,饭当然也是要自己吃……用静态代理实现如下

 

要做的事情(接口)

package com.hk.service;
/**
 * 定义一个接口(一类人要做的事情)
 * @author 浪丶荡
 *
 */
public interface ISomeService {
    //打官司
    public String Litigate();
    //吃饭
    public String eat();
}

如果自己做,做的方式是(目标类)

package com.hk.service;
/**
 *  目标类
 * @author 浪丶荡
 *
 */
public class ISomeServiceImp implements ISomeService {

    @Override
    public String Litigate() {
        return "自己打官司,输了";
    }

    @Override
    public String eat() {
        return "自己吃饭";
    }

}

专业律师(代理类)

package com.hk.service;
/**
 *  代理类
 * @author 浪丶荡
 *
 */
public class ServiceProxy implements ISomeService {
    //客户
    private ISomeService target;

    public ServiceProxy() {
    }
    //联系客户接受任务,为谁打官司
    public ServiceProxy(ISomeService target) {
        this.target = target;
    }

    //帮客户打官司
    @Override
    public String Litigate() {
        return "律师打官司,赢了";
    }
    //吃饭就让客户自己吃吧
    @Override
    public String eat() {
        return target.eat();
    }

}

演绎过程(测试类)

package com.hk.test;

import com.hk.service.ISomeService;
import com.hk.service.ISomeServiceImp;
import com.hk.service.ServiceProxy;
public class MyTest {
    public static void main(String[] args) {
        //有money人张三
        ISomeService zhangsan = new ISomeServiceImp();
        //屌丝李四
        ISomeService lisi = new ISomeServiceImp();

        //张三请的律师打官司,饭自己吃
        ISomeService sp = new ServiceProxy(zhangsan);
        System.out.println("zhangsan"+sp.Litigate()+"-----"+sp.eat());
        //苦逼的李四自己打官司,自己吃饭
        System.out.println("lisi"+lisi.Litigate()+"-----"+lisi.eat());
    }
}

结局(结果)

zhangsan律师打官司,赢了-----自己吃饭
lisi自己打官司,输了-----自己吃饭

 动态代理:

动态代理是指客户通过代理类来调用其他对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对象。

动态代理使用场合:

        调试

        远程调用方法(像android中的AIDL)

 

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

import javax.script.Invocable;

//动态代理的使用,体会反射是动态语言的关键
interface Subject{
	void action();
	
}
//被代理类
class RealSubject implements Subject {
	public void action(){
		System.out.println("我是被代理类。记得要执行我哦!");
	}
}

class MyInvocationHandler implements InvocationHandler{
	Object obj;//实现了接口的被代理类的对象声明
	//给被代理的对象实例化。返回一个代理类对象
	public Object blind (Object obj){
		this.obj =obj;
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this );
	}
	//当通过代理类的对象发起对被重写的方法的调用时,都会转换为对如下的invoke方法的调用
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		//method方法的返回值时returnVal
		Object returnVal = method.invoke(obj,args);
		return returnVal;
	}
	
}
public  class Test1{
	public static  void main(String[] args){
		//1.被代理类的对象
		RealSubject real = new RealSubject();
		//2.创建一个实现了invocationHandler接口的类的对象
		MyInvocationHandler handler = new MyInvocationHandler();
		//3.调用blind()方法,动态的返回一个同样实现了real所在类实现的接口Subject的代理类的对象
		Object obj = handler.blind(real);
		Subject sub = (Subject)obj;//此时sub就是代理类的对象
		sub.action();//转到对invocationHandler接口的实现类的invoke方法的调用
		
		
		
	}
}

 

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