设计模式之代理模式:武器附魔之道

电子说

1.4w人已加入

描述

作者:京东保险 孙昊宇

大家好,今天我们聊聊设计模式中的代理模式。作为一种经典设计模式,它的应用极为广泛。不论你是刚刚入门,还是已经熟悉设计模式,相信这篇文章都会让你有所收获。

一、引子:叫个代驾

让我们从一个引子开始:司机和代驾。「私家车司机」和「代驾」是什么关系?很简单,「私家车司机」是客户,「代驾」负责提供服务,帮他们开车。

不同点: 「私家车司机」有自己的车,他们可能自己开车,也可能找代驾开车;

「代驾」没有自己的车,但他们会接到代驾订单,从而开「私家车司机」的车。

相同点: 他们都会开车,有驾照。换句话说,他们都属于「司机」。

说到这里,我想他们的关系就很清楚了:「司机」是「私家车司机」和「代驾」的父类。虽然都会开车,但他们对“开车”这个行为有不同的实现。

让我们把这三个类的关系表示出来。首先定义一个抽象类「司机」,就叫Driver好了:

 

@Data
public abstract class Driver {

    String name;

    abstract void driveCar();
}

 

我们要求每个司机都有一个名字,且都必须会开车。

接下来看看「私家车司机」,CommonDriver类:

 

@Data
public class CommonDriver extends Driver {

    CommonDriver(String name) {
        this.name = name;
    }

    @Override
    public void driveCar() {
        System.out.println(this.getName() + "的汽车正在行驶...");
    }
}

 

也很简单,每次开车的时候打印一行日志即可。最后看看「代驾」,就叫ProxyDriver吧:

 

@Data
public class ProxyDriver extends Driver {

    private Driver realDriver;

    ProxyDriver(String name, Driver realDriver) {
        this.name = name;
        this.realDriver = realDriver;
    }

    @Override
    void driveCar() {
        System.out.printf("代驾「%s」正在为%s服务...n", this.getName(), this.getRealDriver().getName());
        this.realDriver.driveCar();
    }
}

 

我们要求每个代驾都要有一个服务的客户,也就是被代理的司机。我们将这位被代理的司机——realDriver作为了代驾类的私有变量存起来。当代驾在开车时,他实际上开的是客户的车。因此,他直接去调用realDriver的开车方法即可。

三个类定义好了,让我们先创建一个「私家车司机」——小张,让小张自己开车;再帮他叫一个「代驾」——就叫他小代吧,让小代帮他开车:

 

public class Main {
    public static void main(String[] args) {
        CommonDriver zhang = new CommonDriver("小张");
        zhang.driveCar();
        ProxyDriver proxyDriver = new ProxyDriver("小代", zhang);
        proxyDriver.driveCar();
    }
}

 

运行一下:

小张的汽车正在行驶... 代驾小代正在为小张服务... 小张的汽车正在行驶...

结果符合预期:不管是谁在开车,结果都是一样的,开的都是小张的汽车。

二、代理模式:武器附魔之道

代理模式的定义

以上例子展示了一个代理模式的基本实现。代理模式(Proxy Pattern) 的定义是:使用代理以代替对真实对象的访问。 它属于一种结构型设计模式。

例子中的「司机」、「私家车司机」和「代驾」三个角色,分别对应了代理模式中的三个基本元素:

「私家车司机」——真实主题: 被代理的角色,是业务逻辑的具体执行者。

「代驾」——代理主题: 负责代理真实主题,所有对其业务方法的调用,都会被委托给其真实主题实现。

「司机」——抽象主题: 可以是接口,也可以是抽象类。代理主题和真实主题都会去实现/继承同一个抽象主题。

优点及应用

为真实的对象设置一个代理,可以带来什么好处?在哪些应用场景下,我们需要用到代理模式?

要回答这个问题,我们不妨想想代理的特点:间接访问。没错,代理模式的优点就在于通过代理间接访问真实对象。通过间接访问,我们就可以让代理做许多中间操作,通过这些中间操作,我们就可以在不修改真实对象的前提下,实现功能增强。

我的理解:如果把真实主题比做一把**「宝剑」,专门用来处理核心逻辑**,那么就可以将它的代理比作**「附魔」,用来给真实主题提供一些强化功能**,附魔的种类就很多啦:火焰

审核编辑 黄宇

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分