代理模式属于结构型模式
某些情况下,一个对象不能或不想直接访问另一个对象,
需要给被访问对象提供一个代理,以控制访问者对该对象的访问,
代理对象代表被访问对象的功能,作为访问者和被访问对象之间的媒介。
包含抽象主题、具体主题、代理类三个角色,具体主题、代理类都应该实现抽象主题。
静态代理
我们以遥控汽车为例
玩具(抽象主题)
package com.example.duohoob.dp.proxy;
/**
* 玩具、抽象主题
* @Title: Toy.java
* @Package com.example.duohoob.dp.proxy
*
* @author yangwei
* @date 2022年7月5日
*/
public interface Toy {
public void run();
}
玩具小汽车(具体主题)
package com.example.duohoob.dp.proxy;
/**
* 玩具小汽车、具体主题
* @Title: Car.java
* @Package com.example.duohoob.dp.proxy
*
* @author yangwei
* @date 2022年7月5日
*/
public class Car implements Toy {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("玩具小汽车跑的真快");
}
}
遥控器(代理类)
package com.example.duohoob.dp.proxy;
/**
* 遥控器、代理类
* @Title: Telecontrol.java
* @Package com.example.duohoob.dp.proxy
*
* @author yangwei
* @date 2022年7月5日
*/
public class ProxyTelecontrol implements Toy {
private Car car;
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("遥控控制小汽车开跑");
if (null == car) {
car = new Car();
}
car.run();
}
}
访问对象
package com.example.duohoob.dp.proxy;
/**
* 相当于访问对象
* @Title: ProxyTest.java
* @Package com.example.duohoob.dp.proxy
*
* @author yangwei
* @date 2022年7月5日
*/
public class ProxyTest {
public static void main(String[] args) {
// 遥控小汽车
ProxyTelecontrol toyCar = new ProxyTelecontrol();
toyCar.run();
}
}
运行
动态代理
静态代理中,
当被代理对象方法增加时,代理类需要同步改动,这是比较麻烦的。
运用Java的反射机制,
生成被代理对象,代理类不需要关心抽象主题中有哪些方法。
package com.example.duohoob.dp.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 动态代理类
* @Title: DynamicTelecontrol.java
* @Package com.example.duohoob.dp.proxy
*
* @author yangwei
* @date 2022年7月5日
*/
public class DynamicTelecontrol {
private Car car;
public Toy getProxy() {
System.out.println("遥控开始控制小汽车");
if (null == car) {
car = new Car();
}
// 运用Java的反射机制,生成被代理对象,代理类不需要关心抽象主题有哪些方法
Toy toy = (Toy) Proxy.newProxyInstance(this.getClass().getClassLoader(), car.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
return method.invoke(car, args);
}
});
return toy;
}
public static void main(String[] args) {
DynamicTelecontrol dt = new DynamicTelecontrol();
Toy toy = dt.getProxy();
toy.run();
}
}
运行