前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java设计模式(七)代理模式

Java设计模式(七)代理模式

作者头像
每天学Java
发布2020-06-01 18:03:17
4210
发布2020-06-01 18:03:17
举报
文章被收录于专栏:每天学Java每天学Java

学代理模式(静态代理,下面所属都指的是静态代理)的时候,敲着敲着代码,觉得怎么感觉像在写装饰器模式一样。所以在叙述代理模式的时候,我会用自己的理解去区分两种模式的区别。

在我上大学的城市,是没有苹果直营店的,但是有苹果的授权店,这个授权店概念就可以理解为代理。通过这个授权店我们同样能买到苹果的产品。

那么我怎么理解代理模式和装饰器模式的区别呢?首先看你的目的:你是需要在一个类上面增加功能(而且增加的功能还是动态的,可能不同的客户端会增加不一样的功能),那么这个时候你大致知道你要用装饰器模式了。或者你需要在使用类上面一个功能,同时加一点自己东西(也是增强功能),但是这个类是一个包级别的(比如苹果直营店在杭州,而我在河南),外部包无法直接取到这个类,那么你应该找一个代理了(河南的苹果代理),把需要的功能让代理类代理出去(去代理那里买苹果)。

我再说的直白点就是,你要访问国外网站,你需要翻墙才行,我可以把翻墙软件当作一个代理,通过它你就可以访问国外网站,与此同时这个翻墙软件(代理)也可以对你的访问做一些限制(某些网站,可能代理也不会让你访问)。而如果说你需要提高家里的无线网的网速,你可以自己掏钱升带宽,买一个更好的路由器,这个时候提升了网速,但是你对网速这个东西没有做任何改变。你只是提示了它的速度,速度再快它的本质也没改变。

所以说两种模式,在表面上给我我们都是增加功能的效果,但是实际上他们是为了解决不一样的问题,而产生的两种模式,你可以认为他们可以实现相同的目的(因为某些地方既可以有苹果直营店,也有授权店。在这里面你可以买到一样的东西,但是你能说他们是一样的吗),所以你不能说两种模式是一样的,可能在一些特定的情况下两种模式都可以用。

以上的话是对了解代理模式和装饰器模式小伙伴,说一说我的理解。如果你有更好的见解,欢迎留言。下面就来步入正题,看一下代理模式。

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

既然代理模式和装饰器模式很像,那么被代理的类和代理类肯定首先要共有一个接口。这里我们来写一个超市的接口

代码语言:javascript
复制
//超市
public interface Supermarket {
    //零食
    void snacks();

    //家具
    void furniture();

    //服装
    void clothing();

    //日用品
    void dailyNecessities();

}

现在超市的接口有了,那么我们来实现一个沃尔玛超市,注意这个WalMart是包级的,也就是在包外你是无法实例的,你可以理解为这个沃尔玛在美国,而我们在国内,为了逛个超市去美国开销太大,怎么办呢?中国也有沃尔玛的代理啊,去它们那里啊。

代码语言:javascript
复制
//沃尔玛
 class WalMart implements Supermarket {

    @Override
    public void snacks() {
        System.out.println("这里有沃尔玛零食");
    }

    @Override
    public void furniture() {
        System.out.println("这里有沃尔玛家具");
    }

    @Override
    public void clothing() {
        System.out.println("这里有沃尔玛服装");
    }

    @Override
    public void dailyNecessities() {
        System.out.println("这里有沃尔玛日用品");
    }
}

既然我们无法访问美国的沃尔玛,我们只能访问代理,但是我们要知道这是在沃尔玛允许下,才会代理的,所有代理类我们要设置为public,此外这个代理目前只能代理零食。

代码语言:javascript
复制
//沃尔玛的代理
public class WalMartProxy implements Supermarket {
    WalMart walMart = new WalMart();

    @Override
    public void snacks() {
        walMart.snacks();
    }

    @Override
    public void furniture() {

    }

    @Override
    public void clothing() {

    }

    @Override
    public void dailyNecessities() {

    }
}

现在我们就想去逛沃尔玛的代理超市了,

代码语言:javascript
复制
public class Study {
    public static void main(String[] args) {
        Supermarket supermarket = new WalMartProxy();
        supermarket.snacks();
    }

}

在这里我们就通过代理买到沃尔玛的零食了,对于这种直接创建实例很困难的对象,我们可以通过代理来达到想要的效果,为什么说代理类可以控制被代理类呢?虽然被沃尔玛有权收回代理的授权,但是同样我也可以不要代理的权限,而且我还能买别人的零食,对于家具服装你不给我授权,我可以代理卖华联的家具服装,或者我自己进货去卖。

代码语言:javascript
复制
//沃尔玛的代理
public class WalMartProxy implements Supermarket {
    WalMart walMart = new WalMart();

    @Override
    public void snacks() {
        System.out.println("这里有其他的零食");
        //如果不想让人买沃尔玛的零食了,或者零食卖完了,我们可以动态控制这个方法的调用
        walMart.snacks();
    }

    @Override
    public void furniture() {
    System.out.println("虽然我没有代理沃尔玛家具,但是这里有我自己做家具");
    }

    @Override
    public void clothing() {

    }

    @Override
    public void dailyNecessities() {

    }
}

优点: 1、职责清晰。 2、高扩展性。 3、智能化。

缺点: 1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

使用场景:按职责来划分,通常有以下使用场景: 1、远程代理。 2、虚拟代理。 3、Copy-on-Write 代理。 4、保护(Protect or Access)代理。 5、Cache代理。 6、防火墙(Firewall)代理。 7、同步化(Synchronization)代理。 8、智能引用(Smart Reference)代理。

说到这里对于代理类你有没有一个自己的理解呢?

欢迎进入小程序:

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 每天学Java 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档