代理模式
(Proxy Pattern):为其他对象提供一种代理以控制
对这个对象的访问
。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
角色分为:
抽象角色
:通过接口或抽象类声明
真实角色实现的业务方法。
代理角色
:实现抽象角色
,是真实角色的代理
,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
真实角色
:实现抽象角色
,定义真实角色所要实现的业务逻辑
,供代理角色调用
。
优点:
(1)职责清晰
:真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务
,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
(2)代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象
的作用。
(3)高扩展性
代理模式
分为静态代理
、动态代理
。
静态代理
是由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前
就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
动态代理
是在实现阶段不用关心代理类,而在运行阶段
才指定哪一个对象。
静态代理示例:
//接口
public interface Image {
void display();
}
//具体实现
public class RealImage implements Image{
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadFromDisk();
}
private void loadFromDisk() {
System.out.println("Loading"+filename);
}
@Override
public void display() {
System.out.println("Displaying"+filename);
}
}
//代理类
public class ProxyImage implements Image{
private RealImage realImage;
private String filename;
public ProxyImage(String filename) {
this.filename = filename;
}
@Override
public void display() {
if (realImage==null){
realImage=new RealImage(filename);
}
this.filename=filename;
}
}
//测试类
public class Test {
public static void main(String[] args) {
Image image=new ProxyImage("ssfs.jpg");
//图像需要时加载
image.display();
}
}
// 动态代理处理器
class ImageInvocationHandler implements InvocationHandler {
private Object image;
public ImageInvocationHandler(Object image) {
this.image = image;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 在这里可以添加额外的逻辑
return method.invoke(image, args);
}
}
// 客户端
public class DynamicProxyExample {
public static void main(String[] args) {
// 真实的图片对象
Image realImage = (Image) new RealImage("image.jpg");
// 获取动态代理
Image proxyImage = (Image) Proxy.newProxyInstance(
Image.class.getClassLoader(), // 类加载器
new Class<?>[]{Image.class}, // 代理需要实现的接口
new ImageInvocationHandler(realImage) // 调用处理器
);
// 图像将在需要时加载
proxyImage.display();
}
}