您的位置:首页 > 其它

设计模式之禅笔记7--代理模式

2017-01-23 00:21 555 查看

代理模式

定义:为其他对象提供一种代理以控制对这个对象的访问。

角色如下:

1. Subject抽象主题角色

2. RealSubject具体主题角色。也叫做被委托角色。

3. Proxy代理主题角色。也叫做代理类,委托类。

public interface Subject {

//定义一个方法
public void  request();
}
public class RealSubject implemnts Subject{
//实现方法
public void request(){
//业务处理
}
}
public class Proxy implements Subject{
//要代理哪个实现类
private Subejct subejct = null;
//默认被代理者
public Proxy(){
this.subject = new proxy();
}
//通过构造函数传递代理者
public Proxy(Object...objects){

}
public proxy(Subject subject){
this.subejct = subject;
}
//实现接口中定义的方法
public void request(){
this.before();
this.subject.request();
this.after();
}
public void before(){do Something}
public void after(){do Something}
}


优点:

1. 职责清晰

2. 高扩展性

3. 智能化

普通代理:客户端只能访问代理角色,而不能访问真实角色。

强制代理:一般的思维是要通过代理找到真实的角色。但是强制代理是通过真实角色找到代理角色。否则你不能访问。即先new出一个真实角色,再通过真实角色的getProsy()方法得到代理角色。客户端再调用代理角色的方法。

代理是有个性的:代理类不仅仅可以实现主题接口,也可以实现其他接口完成不同的任务。代理的目的就是在目标对象方法的基础上增强,其本质是对目标对象方法进行拦截和过滤。

动态代理

在实现阶段不用关心代理谁,而在运行阶段才指定代理哪一个对象。相对来说,自己写代理类就是静态代理。以打游戏为例。其中InvocationHandler是JDK提供的动态代理接口,对被代理类的方法进行处理。

//动态代理类
public class GamePlayIH implements InvocationHandler{
//被代理者
Class cls = null;
//被代理的实例
Object obj = null;
//我要代理谁
public GamePlayIH(Object _obj){
this.obj = _obj;
}
//调用被代理类的方法
public Object invoke(Object proxy,Method method,Object[] args){
Object result = mehtod.invoke(this.obj,args);
return result;
}
}


invoke方法是接口InvocationHandler定义必须实现的。他完成对真实方法的调用。

public class Client{
public static void main(String[] args) throws Throwable{
//定义一个痴迷的玩家
IGamePlayer player = new GamePlayer("张三");
//定义个Handler
InvocationHandler handler = new GamePlayIH(player);
//开始打游戏
System.out.println("开始时间是:2009-8-25 10:45");
//获得类的Class loader
ClassLoader cl = player.getClass().getClassLoader();
//动态产生一个代理者
IGamePalyer proxy = (IGamePalyer )Proxy.newProxyInstance(cl,new Class[]{IGamePalyer.class},handler);
//登录
proxy.login("zhngshan","password");
proxy.killBoss();
proxy.upgrade();
System.out.println("游戏时间结束");
}
}


动态代理的通用源码:

public interface Subject {
public void doSomething(String abc);
}
public class RealSubject implements Subject {

//业务操作
public void doSomething(String str) {
System.out.println("do something!---->" + str);
}

}
public class MyInvocationHandler implements InvocationHandler {
private Object target = null;
public MyInvocationHandler(Object _obj){
this.target = _obj;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return method.invoke(this.target, args);
}
}
public class DynamicProxy<T> {

public static <T> T newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h){
if(true){
(new BeforeAdvice()).exec();
}
return (T)Proxy.newProxyInstance(loader,interfaces, h);
}
}
public interface IAdvice {
public void exec();
}
public class BeforeAdvice implements IAdvice{

public void exec(){
System.out.println("我是前置通知,我被执行了");
}
}
public class AfterAdvice implements IAdvice {

public void exec() {
System.out.println("我是后置通知,我被执行了");
}

}
public class Client {

public static void main(String[] args) {
Subject subject = new RealSubject();

Subject proxy = SubjectDynamicProxy.newProxyInstance(subject);

proxy.doSomething("Finish");
}
}


一个类的动态代理是这样的,由InvocationHandler的实现类实现所有的方法,由其invoke方法接管所有方法的实现,其调用过程如下图:



以上的Dynamicproxy类不具有业务意义,是一个通用类。可以增加一个具有业务的动态代理:

public class SubejctDynamicProxy extends DynamicProxy{
public static <T> T newProxyInstance(Subject subject){
ClassLoader loader = subject.getClass().getClassLoader();
Class<?> calsses = subejct.getClass().geInterfaces();
InvocationHandler handler = new MyInvocationHandler(subject);
return newProxyInstance(loader,classes,handller);
}
}


注:要实现动态代理的首要条件:被代理类必须实现一个接口。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式