前段时间找工作时,复习了一下设计模式,当时在写静态代理demo时想偷个懒,便用Runnable做抽象主题接口,于是就发现了些新东西,给大家分享一下。
代理模式简介
代理模式是一种设计模式,它为一个对象提供一个代理或替代,以便控制对该对象的访问。代理模式允许我们在不直接访问原始对象的情况下与它进行交互,也可以添加额外的功能或修改其行为。
Java中的代理按照代理类生成时机不同又分为静态代理和动态代理。静态代理代理类在编译期就生成,而动态代理代理类则是在Java运行时动态生成。动态代理又有JDK代理和CGLib代理两种。
代理模式结构
代理(Proxy)模式分为三种角色:
- 抽象主题(Subject)类: 通过接口或抽象类声明真实主题和代理对象实现的业务方法。
- 真实主题(Real Subject)类: 实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
- 代理(Proxy)类 : 提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。
例如飞机票,可以通过 “携程APP” 、“旅行社”代理 “航空公司” 进行机票的销售。
- “卖机票的能力”就是抽象主题类,“国航卖票” 和 “东航卖票” 就是 真实主题类,“携程APP” 、”旅行社“ 就是代理类。
我的静态代理demo
- 抽象主题类Runnable
- 真实主题类ProxyItem
- 代理类StaticProxy
/**
* 被代理对象
*/
public class ProxyItem implements Runnable {
@Override
public void run() {
System.out.println("我是被代理对象:::我出来表演了");
}
}
/**
* 静态代理类
*/
public class StaticProxy implements Runnable {
private Runnable item ;
public StaticProxy(Runnable item) {
this.item = item;
}
@Override
public void run() {
System.out.println("我要开始代理了==》");
item.run();
System.out.println("我要完成代理了《==");
}
}
//测试代码
public static void main(String[] args) {
StaticProxy staticProxy = new StaticProxy(new ProxyItem());
staticProxy.run();
}
测试结果
回头看看StaticProxy类
大家再看看StaticProxy类,是否感觉有些熟悉?
还不不熟悉?那要不把StaticProxy换个名字为Thread。
这下你该猜到我要说什么了吧?
还没猜到?那我再附上一段Thead 类的源码给看官瞧瞧
public class Thread implements Runnable {
//省略阅读无关代码....
private Runnable target;
//省略阅读无关代码...
//参数为Runnable的构造函数
public Thread(Runnable target) {
//下面这句与阅读相关逻辑为:this.target = target;
init(null, target, "Thread-" + nextThreadNum(), 0);
}
//省略阅读无关代码...
public void run() {
if (target != null) {
target.run();
}
}
//省略阅读无关代码...
}
对比代理类StaticProxy和Thread
//简化后只剩一个Runnable 参数构造函数的Thread类
public class Thread implements Runnable {
private Runnable target;
public Thread(Runnable target) {
this.target = target;
}
public void run() {
target.run();
}
}
//简化后的代理类StaticProxy
public class StaticProxy implements Runnable {
private Runnable item ;
public StaticProxy(Runnable item) {
this.item = item;
}
public void run() {
item.run();
}
}
public class ProxyItem implements Runnable {
public void run() {
//
}
}
代理类StaticProxy 实现和传入Runnable 构造Thead()的实现完全一样呀,也就是说Thread类实现了Runable接口进行了代理。
再简短点,Thread类使用了静态代理模式。