作者:京东保险 孙昊宇
大家好,今天我们聊聊设计模式中的代理模式。作为一种经典设计模式,它的应用极为广泛。不论你是刚刚入门,还是已经熟悉设计模式,相信这篇文章都会让你有所收获。
一、引子:叫个代驾
让我们从一个引子开始:司机和代驾。「私家车司机」和「代驾」是什么关系?很简单,「私家车司机」是客户,「代驾」负责提供服务,帮他们开车。
不同点: 「私家车司机」有自己的车,他们可能自己开车,也可能找代驾开车;
「代驾」没有自己的车,但他们会接到代驾订单,从而开「私家车司机」的车。
相同点: 他们都会开车,有驾照。换句话说,他们都属于「司机」。
说到这里,我想他们的关系就很清楚了:「司机」是「私家车司机」和「代驾」的父类。虽然都会开车,但他们对“开车”这个行为有不同的实现。
让我们把这三个类的关系表示出来。首先定义一个抽象类「司机」,就叫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) 的定义是:使用代理以代替对真实对象的访问。 它属于一种结构型设计模式。
例子中的「司机」、「私家车司机」和「代驾」三个角色,分别对应了代理模式中的三个基本元素:
「私家车司机」——真实主题: 被代理的角色,是业务逻辑的具体执行者。
「代驾」——代理主题: 负责代理真实主题,所有对其业务方法的调用,都会被委托给其真实主题实现。
「司机」——抽象主题: 可以是接口,也可以是抽象类。代理主题和真实主题都会去实现/继承同一个抽象主题。
下面是代理模式的类图:
优点及应用
为真实的对象设置一个代理,可以带来什么好处?在哪些应用场景下,我们需要用到代理模式?
要回答这个问题,我们不妨想想代理的特点:间接访问。没错,代理模式的优点就在于通过代理间接访问真实对象。通过间接访问,我们就可以让代理做许多中间操作,通过这些中间操作,我们就可以在不修改真实对象的前提下,实现功能增强。
我的理解:如果把真实主题比做一把**「宝剑」,专门用来处理核心逻辑**,那么就可以将它的代理比作**「附魔」,用来给真实主题提供一些强化功能**,附魔的种类就很多啦:火焰
标签:动态,代理,小张,之道,ProxyDriver,代驾,附魔,设计模式,public From: https://www.cnblogs.com/Jcloud/p/18643644