代理模式

什么是代理模式?

类似于中介,我们面对的对象变成了中介,而不是用户个体,例如租房子:

image-20220531153138579.png

1、静态代理

角色分析:

  • 抽象角色:真实的目的性,一般是接口或者抽象类来解决
  • 真实角色:被代理的角色
  • 代理角色:代理真实角色,代理真实角色后,一般进行一些附属操作
  • 客户:访问代理对象的人,办理真实业务的人

步骤:

1.接口

public interface Rent {
    //租房
    void rent();
    
}

2.真实角色

public class Landlord implements Rent{
    public void rent() {
        System.out.println("房东出租了房子~");
    }
}

3.代理角色

public class Proxy implements Rent {

    private Landlord landlord;

    public Proxy() {
    }

    public Proxy(Landlord landlord) {
        this.landlord = landlord;
    }

    //额外的操作
    public void seeHouse(){
        System.out.println("中介带看房~");
    }
    public void hetong(){
        System.out.println("中介签合同~");
    }
    public void fare(){
        System.out.println("中介收租~");
    }

    public void rent() {
        seeHouse();
        hetong();
        //真实的租房业务
        landlord.rent();
        fare();
    }
}

4.访问

public class Client {

    public static void main(String[] args) {
        //房东
        Landlord landlord = new Landlord();
        //中介代理房东
        Proxy proxy = new Proxy(landlord);
        //租房业务
        proxy.rent();
    }
}

5、结果

/**
中介带看房~
中介签合同~
房东出租了房子~
中介收租~
/

真实的租房业务还是房东,但是在中介代理后会进行了一些附加的操作。

优点

  • 真实的业务对象更加关注自己的业务,不用在意一些公共的业务
  • 公共交给代理,实现了业务分工
  • 在不修改目标对象的功能前提下, 能通过代理对象对目标功能扩展

缺点

  • 每一个实际的对象都对应一个代理对象,复杂度增加
  • 一旦公共接口增加方法,目标对象与代理对象都要维护

2、动态代理

  • 动态代理角色和静态代理是一样的
  • 动态代理的代理类是动态生成的,不是直接写好的
  • 动态代理分两大类:基于接口的动态代理,基于类的动态代理
    • 基于接口: JDK动态代理
    • 基于类:cglib
    • java字节码实现:javassist

需要理解两个类:PorxyInvocationHandler

Porxy:提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类,专门用来创建代理对象。

InvocationHandler:是调用代理实例的程序实现的接口,动态实现,每个代理实例都有一个关联的调用处理程序。 当在代理实例上调用方法时,方法调用将被编码并分派到其调用处理程序的invoke方法。

还是以租房子为例:

1.接口

public interface Rent {

    void rent();

}

2.真实对象

public class Landlord implements Rent {
    public void rent() {
        System.out.println("房东出租了房子~");
    }
}

3.真实对象处理类

public class ProxyInvocationHandler implements InvocationHandler {
    //被代理的接口 这里可以通配
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    //动态的获取代理类 固定写法
    public Object getPorxy(){
        /**
         * 参数
         *loader - 类加载器来定义代理类
         * interfaces - 代理类实现的接口列表
         * h - 调度方法调用的调用处理函数
         */
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }

    //处理被代理的实例 返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        seeHouse();
        hetong();
        //真实的租房业务
//        this.log(method.getName());
        //处理真实的代理对象业务
        Object result = method.invoke(target,args);
        fare();
        return result;
    }

    //额外的操作
//    public void log(String msg){
//        System.out.println("操作了"+msg+"方法");
//    }
    public void seeHouse(){
        System.out.println("中介带看房~");
    }
    public void hetong(){
        System.out.println("中介签合同~");
    }
    public void fare(){
        System.out.println("中介收租~");
    }

}

4.测试

public static void main(String[] args) {
    //真实对象
    Landlord landlord = new Landlord();

    ProxyInvocationHandler handler = new ProxyInvocationHandler();
    //告诉处理器要代理的真实对象
    handler.setTarget(landlord);
    //获取代理角色 动态生成的
    Rent porxy = (Rent) handler.getPorxy();
    //调用真实的业务
    porxy.rent();
}

结论:

这里的代理对象是通过处理类动态的获取的,而且通过通配改造之后,该处理类可以代理一类的需要代理的对象,只要是实现了同一个接口的对象都可以动态的获取到代理对象。

优点:

  • 基于静态代理的基础上,一个动态代理类代理的是一个接口,一般就是对应的一类业务
  • 一个动态代理类可以代理多个类,只要是实现了同一个接口的
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容