设计模式总结7--代理模式

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

代理模式一般涉及到三个角色
抽象角色:声明真实对象和代理对象的共同接口;
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操
作真实对象,同时代理对象提供与真实对象相同的接口以便在任何
时刻都能代替真实对象。同时,代理对象可以在执行真实对象操
作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。

抽象角色

public interface Subject {

    public void sales();
}

代理角色

public class ProxySubject implements Subject{

    private Subject subject;
    public ProxySubject(Subject subject) {
        this.subject = subject;
    }

    @Override
    public void sales() {
        System.out.println("before");
        subject.sales();
        System.out.println("after");
    }
}

真实角色

public class Dell implements Subject{

    @Override
    public void sales() {
        System.out.println("Dell sales");
    }

}

测试

public class Test {

    public static void main(String[] args) {
        /* 买dell电脑找代理,传入真实对象*/
        ProxySubject proxy = new ProxySubject(new Dell());
        proxy.sales();

    }
}

---------------------------------------------------------------
---------------------------------------------------------------
动态代理:自动生成一个代理类
第一种:使用Java内置的(必须实现某个接口,动态产生目标对象的实现类)
第二种:使用一个库:cglib(动态产生一个目标对象的子类)

第一种

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

public class MyHandler implements InvocationHandler {

    //被代理对象(目标对象)
    private Object target;
    public MyHandler(Object obj) {
        this.target = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("before advice");
        /*代表目标对象的某个方法执行 */
        Object result = method.invoke(target,args);
        System.out.println("after advice");
        return result;
    }

}

测试

public class Test {

    public static void main(String[] args) {

        Dell dell = new Dell();
        MyHandler handler = new MyHandler(dell);
        /*代理对象要传入三个参数:目标对象的ClassLoader,目标对象实现了哪些接口 ,handler
            会返回一个实现了Subject接口的对象,并且它还代理了目标对象*/

        Subject subject = (Subject) Proxy.newProxyInstance(dell.getClass().getClassLoader(), dell.getClass().getInterfaces(), handler);
        subject.sales();

    }
}

有个缺点:就是必须实现某个接口
Subject subject = (Subject) Proxy.newProxyInstance(dell.getClass().getClassLoader(), dell.getClass().getInterfaces(), handler);
如果没有实现,而是拿真实角色来接受就会出错
Dell dell = (Subject) Proxy.newProxyInstance(dell.getClass().getClassLoader(), dell.getClass().getInterfaces(), handler);

延伸:
当没有这个接口的时候要怎么实现代理呢。实际上就是用继承

此时这个抽象角色已经不是接口了,而是一个类

public class User {

    public void haha() {
        System.out.println("user haha");
    }
}

若要实现代理,用继承,然后就可以在执行的时候前置和后置可以写自己的,实际上这就是cglib
的原理

public class Son extends User{

    @Override
    public void haha() {
        System.out.println("xxxx");
        super.haha();
        System.out.println("xxxxx");
    }
}

第二种

导入cglib-nodep-xxx.jar

import java.lang.reflect.Method;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class MyMethodInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object obj, Method arg1, Object[] args,
            MethodProxy methodProxy) throws Throwable {
        System.out.println("前置通知");
        Object result = methodProxy.invokeSuper(obj, args);
        System.out.println("后置通知");

        return result;
    }

}

测试

public class Test {

    public static void main(String[] args) {

        User user = new User();

        Enhancer enhancer = new Enhancer();
        /* 传入父类对象 */
        enhancer.setSuperclass(user.getClass());
        /* 传入MyMethodInterceptor,执行son的时候会自动执行里面的前置还有后置*/
        enhancer.setCallback(new MyMethodInterceptor());
        /* 动态产生user类的子类*/
        User son = (User) enhancer.create();
        son.haha();

    }
}
时间: 2024-10-12 21:08:38

设计模式总结7--代理模式的相关文章

设计模式之动态代理模式

设计模式之动态代理模式 代理模式: Provide a surrogate or placeholder for another object to controlaccess to it(为其他对象提供一种代理以控制对这个对象的访问).使用代理模式创建代理对象,让代理对象控制目标对象的访问(目标对象可以是远程的对象.创建开销 大的对象或需要安全控制的对象),并且可以在不改变目标对象的情况下添加一些额外的功能. 代理模式相关内容详见本人之前文章:http://www.cnblogs.com/zh

设计模式(2)_代理模式 ————— 控制对象访问

设计模式(2)_代理模式 ----- 控制对象访问 一.动机 需求 现在有这样一个需求:有一个出版社,该出版社有一个工厂,专门用来生产制造图书,该工厂里有很多台生产制造图书的机器.每个机器有自己的位置坐标,用 int表示,机器的状态,{正在工作,暂停,故障},已经印刷了多少页图书.在出版社 在工厂 厂长的电脑屏幕上,可以随时打印出任何一台机器的报告信息(report infomation). 下来 我们用代码实现这个需求: PrinterMachine.java package com.crg;

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

一.代理模式的初衷 不想让客户端直接访问具体实现接口,客户端不应该直接访问具体实现,一般会涉及到以下四个对象 业务接口:定义客户端访问的接口,是实现类和代理类都需要实现的 实现类:实现了业务接口,真正的实现是在这里 代理类:同样实现了业务接口,一般都会关联一个实现类的实例,由它来调用实现类 客户端:顾名思义,使用者,与代理类打交道,甚至都不知道具体实现类的存在. 二.代理模式设计图 三.代理模式的简单实现代码 BizInterface.java package com.lipan.designp

设计模式学习--------12.代理模式学习

场景: 福尔摩斯一直想送礼物给花生,但是羞于直接赠送,于是想到让房东太太去帮忙送礼物.编程如何实现呢? 定义: 为其他对象提供一种代理以控制对这个对象的访问. 角色: Proxy:代理对象.有下列功能: 实现与具体的目标对象一样的接口,这样就可以使用代理来代替具体的目标对象. 持有一个具体目标对象的引用,可以在需要时调用具体的目标对象. 可以控制对目标对象的访问,并可以负责创建和删除它. package com.kris.study; public class Proxy implements

【设计模式】Proxy 代理模式

[设计模式]Proxy 代理模式 1.代理模式的定义 代理模式:为另一个对象提供一个替身或占位符以控制对这个对象的访问. 2.静态代理 首先我们通过案例来引出为什么我们需要使用代理模式. 我们给出如下一个接口Moveable 和该接口的实现类: Moveable.java package com.proxy; public interface Moveable { void move(); } Tank.java package com.proxy; import java.util.Rando

设计模式学习之--代理模式

代理模式,顾名思义,意思和我们日常生活中的代理差不多,举一个最简单的例子,我们知道,我们的火车站购票有很多的火车票代售点,这个火车票代售点可以代替我们的火车站的售票处让我们买票,当然,代售点相比于火车站售票点又可以提供电话订票和提前预定,这样,火车票代售点就基本可以实现火车站售票点的基本功能,同时还可以提供相对于火车站售票点其他的功能.那么,我们的设计模式中的代理模式就是这个意思. 在我们的程序中,许多类的方法中我们总需要一些额外的共同的功能,比如日志和性能优化操作,如果在所有 这些类中都加入这

设计模式学习之代理模式学习(一)

关于设计模式想必学习过Java语言的人都知道吧,当时对其进行深入学习的的人应该不是很多.在我看来设计方面的知识相比于框架应用配置等知识要有意思的多,并且设计模式的对一个程序员的编程思想提升有着很大的帮助.但是设计模式有二十三种,想要全部掌握还是要花点时间的,但如果是只学习常用的几种设计模式还是相对容易的.下面是我学习代理模式的一些心得. 问题引出      什么是代理模式,为什么要用代理模式. 现在有一个场景模拟:有一个tank类,他实现了Moveable接口,Moveable接口中有一个mov

php设计模式之Proxy(代理模式)和Facade(外观)设计模式

Proxy(代理模式)和Facade(外观)设计模式它们均为更复杂的功能提供抽象化的概念,但这两种实现抽象化的过程大不相同 Proxy案例中,所有的方法和成员变量都来自于目标对象,必要时,该代理能够对它所传递的数据进行修改或检查魔术方法使得Proxy的实现变的简单,Proxy模式的一类应用时用来记录方法的访问信息还可以利用Proxy的类确定代码的范围或调试程序中存在的问题 <?php class LoggingProxy{ private $target; //传递进去一个对象 public f

设计模式学习之代理模式

代理模式,可以分为两种,一种是静态代理,一种是动态代理. 两种代理从虚拟机加载类的角度来讲,本质上都是一样的,都是在原有类的行为基础上,加入一些多出的行为,甚至完全替换原有的行为.在我们平时写代码的过程中,代理模式可以说是随处可见,所以,本篇博客就将给大家介绍代理模式. 基本概念 代理模式是常用的结构型设计模式之一,当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,所访问的真实对象与代理对象需要实现相同的接口. UML图 Subject:抽

Java设计模式—Proxy动态代理模式

代理:设计模式 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 图 1. 代理模式 为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别.通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间,从而在设计上获得了更大的灵活性.Java 动态代理机制以巧妙的方式近乎完