前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用代理模式优雅地写代码

用代理模式优雅地写代码

作者头像
PhoenixZheng
发布2018-08-07 16:34:00
5490
发布2018-08-07 16:34:00
举报
文章被收录于专栏:Phoenix的Android之旅

Java的代理模式在开发中经常使用,作为设计模式的一种,在很多场景下都有应用。

代理模式通常分为两种 · 静态代理 · 动态代理 关于代理模式,今天先由浅到深说一下静态代理。

没有代理的世界

通常来说,代理模式是用来解耦的,可以把代理模式认为是加入了中介的 Producer/Consumer 模式。 在没有代理的情况下,生产者直接和消费者耦合,这会导致一些问题,比如对某一方的逻辑调整会导致大面积的修改代码。

举一个场景,有个网页向用户提供阅读的功能,产品说你们先把阅读功能上线。 好了现在我们知道有一个统一的动作 read(),抽象出来做为接口吧。

代码语言:javascript
复制
interface Func {
    void read();
}

每个用户都来实现下这个接口,

代码语言:javascript
复制
public class User implements Func {
    void read(){
    ....
    }
}

现在当用户进入我们的网页的时候,我们就可以实例化一个用户对象,然后调用它的read方法。 为了初步解耦,我们用接口来声明,

代码语言:javascript
复制
Func user = new User();
user.read();

so far so good… 虽然我们的代码中到处充斥着这种样板代码,重复的实例化和调用接口,但是需求算是实现了。 然而这样的耦合程度会给自己挖很深的坑,特别是当需求发生变更的时候。 比如下面这样…

引入代理

第一版上线后,用户广泛好评,产品说,既然如此,我们不能免费给用户使用啊,不如我们插个广告吧!

好了,现在我们有两个选择 · 在项目中每个实例调用read()的地方前面插一句 playAdv() · 修改 User的 read()实现逻辑,在前面加个 playAdv()

第一个明显会加大我们的工作量,实例化的地方少还好,要是项目里有几百处地方直接调用实例的接口,我们估计要跪… 第二种虽然相对优雅,可是坑也不小,因为"播放广告"这个行为并不是用户的,我们希望功能尽可能的纯粹。 如果考虑到以后还要区分注册用户/付费用户,第二种修改方式带来的问题也很明显。

其实我们还有第三种选择,引入代理。 先上代理的代码

代码语言:javascript
复制
public class Proxy implements Func {
    private Func mUser;

    public Proxy(Func user) {
        this.mUser = user;
    }

    public void read() {
        mUser.read();
    }
}

上面就是一个简单的代理类的代码了,它也实现了Func的功能, 重点是它的通过构造方法传入了一个被代理的 User对象。 现在我们来看看引入代理有什么好处。

我们的之前调用 User并实例化的地方会变成这样

代码语言:javascript
复制
Proxy proxy = new Proxy(new User());
proxy.read();

咋一看,没什么变化,只是从对 User的调用变成对代理的调用。

但只要仔细思考一下就明白,这样一来,我们就不用关心具体对象的行为了,所有的事情都交给了代理。 当产品说要加个广告时,我们也不需要往用户类里加新逻辑(因为那不是用户行为),我们只需要修改一下代理类,

代码语言:javascript
复制
public class Proxy implements Func {
    private Func mUser;

    public Proxy(Func user) {
        this.mUser = user;
    }

    public void read() {
        AdvUtil.playAdv(); <- 播放广告
        mUser.read();
    }
}

至于调用 Proxy的地方,啥都不用改。 我们用 Proxy,在Producer和Consumer之间加了一层中介,这样一来即使要对Consumer的行为进行干预,也不用到处去修改代码了。

现在因为 Proxy的存在,就算产品再怎么改需求也不怕了。 想加个广告?改一下代理就行。 想加个会员免广告?改一下代理就行。

总结

代理模式总结起来就是通过一层 Proxy层,把 Producer和Consumer之间隔开,让他们之间尽可能的少耦合。 这样当需要操作 Consumer的行为时,只需要修改 Proxy层,而不需要到处去调整 Producer的代码。

但是静态代理的弊端也是很明显的。 当接口的实现类变多时,每次的接口调整也需要修改很多代码。 可以想象一下,加入现在有 免费用户/包月用户/包年用户等类型的用户,包括 Proxy,他们都实现了 Func接口, 此时如果说要给 Func加一个接口,或者给 read()接口加一个参数, 需要调整的代码量也是很可怕的。 所以相对静态代理,就有了动态代理这种神奇的东西。 我们以后再接着分析动态代理的实现和原理。

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

本文分享自 Android每日一讲 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 没有代理的世界
  • 引入代理
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档