那些你要知道的设计模式之-代理

一.定义

  1. 将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

代理在结构上类似装饰着,但目的不同,装饰者模式为对象加上行为,而代理则是控制访问 代理为另一个对象提供代表,以便客户对对象的访问

二.作用

  • 职责清晰真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理
    完成一件事务,附带的结果就是编程简洁清晰。
  • 高扩展性

三.案例

本章将讲解普通代理和动态代理两种代理方式

  • 普通代理
    大学毕业之后大学生们就开始前往不同的城市参加工作,有些公司提供住房还好,但是这种可能性基本不大,于是乎就得考虑住房问题,这个时候市场上就出现了房屋中介商,专门解决这样类似的问题。下面是简单的示意图
普通代理模式

IHouse接口有两个方法房屋位置和房屋大小

public interface IHouse {

    //位置
    void location(String address);

    //大小
    void size(int size);
}

实现类House,这个类主要用来实现具体的业务逻辑,这里只打印这些信息,

public class House implements IHouse {

    @Override
    public void location(String address) {
        System.out.println(address);
    }

    @Override
    public void size(int size) {
        System.out.println(size+"平方");
    }

}

下面是代理模式的核心代理类,通过构造函数定义一个需要被代理的对象,同时它还可以具备自己的方法,作为一个房屋代理者,它还可以告诉你租房所需的费用

public class HomeProxy implements IHouse {

    private IHouse house;

    //构造函数定义一个租房
    public HomeProxy() {
        this.house = new House();
    }

    @Override
    public void location(String address) {
        this.house.location(address);
    }

    @Override
    public void size(int size) {
        this.house.size(size);
        cost(size);
    }


    //合计
    public void cost(int size) {
        System.out.println(size * 5 + tip(size)+"$");
    }


    //中介费
    public double tip(int size) {
        return size * 5 * 0.35;
    }

}

我们模拟一下租房的过程,如下所示:

public static void main(String[] args) {

        //创建一个房屋中介商
        IHouse proxy = new HomeProxy(house);
        //租房的位置
        proxy.location("上海");
        //租房的大小
        proxy.size(100);

    }

运行结果如下:
上海
100平方
675.0$
这种模式下通过构造函数定义一个代理对象,进行代理。调用者只需要知道代理类是谁就可以了,结构更加清晰,屏蔽了
真实角色的变更对高层模块的影响,真是角色只需要实现接口,实现具体的业务逻辑,想怎么改就怎么改,提高了扩展性


  • 动态代理

动态代理需要实现InvocationHandler接口产生一个代理对象,InvocationHandler是JDK本身就提供好的的动态代理接口,这里用HomeIH去实现这个接口

public class HomeIH implements InvocationHandler {

    //被代理的实例
    Object obj;

    //我要代理谁
    public HomeIH(Object _obj) {
        this.obj = _obj;
    }

    //调用被代理的方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        //方法执行之前
        System.out.println("before  " + method.getName());
        //执行被代理的方法
        Object result = method.invoke(this.obj, args);
        return result;
    }
}

这样写之后所有方法都由该Handler来进行处理,所有被代理的方法都由invoke方法去执行,invoke的三个参数分别为proxy(代理对象 ),method(被调用方法),args(被调用方法的参数)还是延续上面的代码,只需将main函数修改如下

 public static void main(String[] args) {

        //被代理实例
        IHouse house = new House();
        //通过构造函数传入到Handler中
        HomeIH handler = new HomeIH(house);
        //动态产生一个代理者
        IHouse proxy = (IHouse) Proxy.newProxyInstance(house.getClass().getClassLoader(),new Class[]{IHouse.class},handler);
        //租房的位置
        proxy.location("上海");
        //租房的大小
        proxy.size(100);

    }

运行之后看结果:
before location
上海
before size
100平方
看到没这就是动态代理,还是通过代理去租房,和普通代理的区别就是,动态代理不用创建代理类,不用实现方法接口,而且更加的灵活,更加的具备扩展性 ,当然,JDK的动态代理有一个需要注意的地方,这里的每个委托类都必须是要有接口的,如果你问我,没有实现接口能不能被代理,我说能

四.总结

代理类不仅仅是一个隔离客户端和委托类的中介。我们还可以借助代理来在增加一些功能,而不需要修改原有代码,完美的体现了开闭原则。
真正的业务功能还是有被代理来实现,但是在实现业务类之前的一些公共服务,或者之后的服务。我们可以通过代理模式来实现

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

推荐阅读更多精彩内容

  • 整体Retrofit内容如下: 1、Retrofit解析1之前哨站——理解RESTful 2、Retrofit解析...
    隔壁老李头阅读 3,236评论 2 10
  • 一声惊蛰的雷 带来了三月的第一场雨 雨淅淅沥沥 下了整整一夜 我在陋室一隅 临窗听雨 听花开的声音 想像草儿努力生...
    风铃_bb0d阅读 241评论 0 5
  • 文件包含 两种方式 cat 作用 查看文件内容 链接文件 创建一个多个文件 重定向输出到终端 重定向到文件 read
    f75dfaf80e43阅读 1,263评论 0 0
  • 今天下午妈妈带我去参加入学考试。妈妈想让我去学奥数。我对妈妈说:“我想去”。妈妈的态度很坚决,她说:“不想去...
    Cherry多多阅读 188评论 0 2