码迷,mamicode.com
首页 > 编程语言 > 详细

Java-代理模式

时间:2017-11-04 11:16:43      阅读:198      评论:0      收藏:0      [点我收藏+]

标签:pre   bsp   ==   ret   java   real   相同   int   情况下   

什么是代理模式?

  代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。举例说明,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用。其实代理的模式就两个字:中介

代理模式的一些应用场景:

  火车站通过黄牛买票,通过4S店买车,通过中介租房,外卖小哥送外卖等等都是代理模式的具体应用。

代理模式分类:

  代理模式大体上可以分为两类,静态代理和动态代理。代理主要通过反射技术来实现的。

代理模式的角色:

ISubject:抽象主题角色,是一个接口。该接口是对象和它的代理共用的接口。
RealSubject:真实主题角色,是实现抽象主题接口的类。
Proxy:代理角色,内部含有对真实对象RealSubject的引用,从而可以操作真实对象。代理对象提供与真实对象相同的接口,以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。

 

静态代理

  静态代理是指代理类是我们手动编写,在程序运行前就编译好的,而不是程序动态生成的代理类,这就是所谓的静态;

代码实现:我们通过外卖小哥送餐这种场景来模拟实现静态代理。

1. 首先创建一个取餐的接口

/**
 * 外卖
 *
 * @author: pc-user
 * @since: 2017 /11/4 8:50
 */
public interface TakeAway {

    /**
     * 取外卖
     */
    void getTakeAway();
}

2. 声明一个要取餐的客人,实现这个接口

/**
 * 用户
 *
 * @author: pc-user
 * @since: 2017/11/4 8:52
 */
public class MyTakeAway implements TakeAway {
    private String name; // 取餐人姓名

    public MyTakeAway(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void getTakeAway() {
        System.out.println(name + "取餐完成");
    }
}

3. 声明一个外卖小哥代理,也必须要实现取餐接口

/**
 * 外卖小哥
 *
 * @author: pc-user
 * @since: 2017/11/4 8:54
 */
public class DeliveryManProxy implements TakeAway {
    private MyTakeAway myTakeAway; //取餐人对象

    public DeliveryManProxy(MyTakeAway myTakeAway) {
        this.myTakeAway = myTakeAway;
    }

    @Override
    public void getTakeAway() {
        System.out.print("外卖小哥帮助");
        myTakeAway.getTakeAway();
    }
}

4. 客户端调用

/**
 * TODO
 *
 * @author: pc-user
 * @since: 2017/11/4 8:56
 */
public class Main {
    public static void main(String[] args) {
        MyTakeAway renter1 = new MyTakeAway("张三");
        MyTakeAway renter2 = new MyTakeAway("李四");
        DeliveryManProxy proxy = new DeliveryManProxy(renter1);
        proxy.getTakeAway();
        proxy = new DeliveryManProxy(renter2);
        proxy.getTakeAway();
    }
}

输出结果:

外卖小哥帮助张三取餐完成
外卖小哥帮助李四取餐完成

  或许我们有疑问,我们可以自己取餐?当然这是可以的,如果实现类能满足我们的需求,我们直接用实现类就可以。然而在应用场景中,当我们要扩展需求,根据设计模式的开闭原则,不建议直接修改实现类,这时候我们就可以通过修改代理类来实现。比如,有一天,我们想取餐的时候顺便去楼下买包烟,我们的实现类是没有买烟这个接口的,这时候我们就可以通过修改代理类来实现。这种情况我们就可以直接修改代理类来实现,而不用动实现类的接口;

/**
 * 外卖小哥
 *
 * @author: pc-user
 * @since: 2017/11/4 8:54
 */
public class DeliveryManProxy implements TakeAway {
    private MyTakeAway myTakeAway; //取餐人对象

    public DeliveryManProxy(MyTakeAway myTakeAway) {
        this.myTakeAway = myTakeAway;
    }

    @Override
    public void getTakeAway() {
        System.out.print("外卖小哥帮助");
        myTakeAway.getTakeAway();
        System.out.print("又顺手");
        buyCigarettes();
    }

    private void buyCigarettes() {
        System.out.println("买了一包烟");
    }
}

测试类不变,运行结果:

外卖小哥帮助张三取餐完成
又顺手买了一包烟
========================
外卖小哥帮助李四取餐完成
又顺手买了一包烟

 

动态代理

 

Java-代理模式

标签:pre   bsp   ==   ret   java   real   相同   int   情况下   

原文地址:http://www.cnblogs.com/xiaozhang2014/p/7782323.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!