代理模式

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

举一个现实中的例子:

1.顾客

2.客服人员

3.程序员

    顾客想向一个公司买一个网站,那么顾客就和客服人员商讨网站细节。客服人员会告诉顾客哪些要求是可以实现,哪些是不能实现的,最后,由客服人员把商讨后的需求告诉程序员,程序员根据需求开始编代码设计网站。

    程序人员和客服人员都有设计网站这个功能,只是真正设计网站的是程序人员,客服只是将整理客户的需求告诉程序员。在这个实践当中,客服人员就是代理对象,而程序员是真正的处理对象。

设计代码:因为客服和程序员都有设计网站这个功能,所以是实现同一个接口。

Proxy(代理接口)

public interface Proxy {
    /**
     * 设计网站
     */
    void designWebSite();
}

CustomerService(客服人员)

public class CustomerService implements Proxy {
    private Programmer programmer = new Programmer();
    private int money;
    @Override
    public void designWebSite() {
        System.out.println("我是客服,我会把需求告诉程序员!");
        programmer.designWebSite();
    }
}

Programmer(程序员)

public class Programmer implements Proxy {

    @Override
    public void designWebSite() {
        System.out.println("我是程序员,我才是帮你写网站的人!");
    }
}

Customer(顾客)

public class Customer {
    public static void main(String[] args) {
        CustomerService customerService = new CustomerService();
        customerService.designWebSite();
    }
}
调用Customer的main(),打印出:

    我是客服,我会把需求告诉程序员!

    我是程序员,我才是帮你写网站的人!

到这里,代码只是体现了代理,并没有体现代理的价值,代理的价值就是控制访问。

在哪里控制?在哪里访问就在哪里控制!

    所以在客服类中要控制访问,例如,顾客和客服说指向花1W元买这个网站,但是公司的标价是5W,这肯定是不允许的,所以客服要不允许这个动作。修改代码如下:

只需要改动CustomerService(客服人员)和Customer(顾客)

CustomerService(客服人员):

public class CustomerService implements Proxy {
    private Programmer programmer = new Programmer();
    private int money;

    public CustomerService(int money) {
        this.money = money;
    }

    @Override
    public void designWebSite() {
        if(money<50000){
            System.out.println("不好意思你的开价太低,我们公司不接受这个交易");
        }else{
            System.out.println("我是客服,我会把需求告诉程序员!");
            programmer.designWebSite();
        }
    }
}

    在CustomerService中加了个money属性,和带有money属性的构造方法。并且在designWebSite()中去判断money,从而控制是否该请求Programmer。

Customer(顾客)

    因为CustomerService的构造方法变了,这里创建CustomerService实例肯定要加参数!

public class Customer {
    public static void main(String[] args) {
        CustomerService customerService = new CustomerService(10000);
        customerService.designWebSite();
    }
}

运行结果是:

    不好意思你的开价太低,我们公司不接受这个交易

这就体现了控制访问的效果。

    很多人会有疑问为什么参数要加在构造方法上,不直接加在代理方法上。原因是,如果加在代理方法,用到代理方法的地方都要改,在这里四个类的代理方法都要手动去改,Proxy接口都改了,这是很不友好的。而加在构造方法上,只要改代理对象和调用对象两个。

代理模式的使用场景一般分为以下几种:

    第一种:远程代理,就是一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。

         方便扩展,常用在处理远程访问中,比如分布式访问。

    第二种:虚拟代理:是根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真是对象。

        浏览器的初始化就是代理模式,图片加载的慢, 就先显示一个未打开的图片框,因为图片大小路径存在代理对象中

    第三种:安全代理:用来控制真是对象的访问时的权限

    第四种:智能指引:是指当调用真是对象时,代理处理另外一些事情。

        比如记录调用真实对象的次数。

    代理模式其实就是在访问对象时引入一定程度的间接性,因为这种间接性,可以附加很多种用途。

    如果以上说的有什么不恰当或不准确的描述,请各位指出,一直在学习中。

    


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值