0x01 前言
静态代理只是一种设计模式,因此不需要任何的包,实现思路即可
注意点一:
静态代理在使用时,需要定义接口或者父类
代理对象与目标对象需要一起实现相同的接口或者是继承相同父类
注意点二:
代理对象与目标对象要实现相同的接口,然后代理对象通过调用相同的方法来调用目标对象的方法
0x02 环境
编辑器为: IntelliJ IDEA
java版本:
java version "1.8.0_271"
Java(TM) SE Runtime Environment (build 1.8.0_271-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.271-b09, mixed mode)
代码仓库: https://github.com/pmiaowu/JavaProxyTest
0x03 例子
例如我们去影院看电影:
我们平常去电影院看电影时,在电影开始与结束阶段是不是都会放广告呢?
电影是电影公司授权给影院进行播放与售卖的
那么电影公司就是目标对象,他只管和影院根据票房分钱,剩下的事情就不关它事了
而影院就是代理对象,负责其他的事情
在例如影院可以在播放电影的前后,产生一些除了电影票之外的额外收益
比如在影片开始与结束时播发一些广告
现在我们使用代码来进行模拟
首先创建个接口,通用的接口是代理模式实现的基础
这个接口就命名为Movie
,里面有个play
方法,表示电影播放的能力
package 静态代理;
public interface Movie {
void play();
}
接着创建个实现这个Movie
接口的类,这个类表示电影公司授权给影院的电影
package 静态代理;
public class RealMovie implements Movie {
@Override
public void play() {
System.out.println("您正在观看电影《嗨客帝国》");
}
}
然后创建个Cinema
类,这个类表示影院要播放的电影,还有一些额外的操作
这个Cinema
类就是个代理对象了
package 静态代理;
public class Cinema implements Movie {
RealMovie movie;
public Cinema(RealMovie movie) {
super();
this.movie = movie;
}
@Override
public void play() {
this.advertising1();
this.movie.play();
this.advertising2();
}
public void advertising1() {
System.out.println("开始广告: 电影准备开始了,肯德基十翅一桶,只需要39元,快来买啊!");
}
public void advertising2() {
System.out.println("结束广告: 电影结束了,肯德基十翅一桶,只需要39元,快买回家吃吧!");
}
}
最后面运行看看结果
package 静态代理;
public class Test {
public static void main(String[] args) {
RealMovie realMovie = new RealMovie();
Movie movie = new Cinema(realMovie);
movie.play();
}
}
// 执行结果
开始广告: 电影准备开始了,肯德基十翅一桶,只需要39元,快来买啊!
您正在观看电影《嗨客帝国》
结束广告: 电影结束了,肯德基十翅一桶,只需要39元,快买回家吃吧!
0x04 总结
好处:
静态代理模式,可以在不改变目标对象的前提下,实现对目标对象的功能扩展
不足:
静态代理模式,代理对象(Cinema)实现了目标对象(RealMovie)所有的方法,一旦目标接口(Movie)增加新方法,代理对象(Cinema)和目标对象(RealMovie)都要进行相应的修改
其次,代理对象(Cinema)里面的每一个类方法,对应一个目标对象(RealMovie),如果目标对象(RealMovie)非常多
则静态代理类就会变的非常臃肿,极大的增加维护成本
例如:现在有一百部影片(继承Movie并实现)出来,那么就要创建一百个影院(Cinema),代码复用率也不高