代理模式

介绍

代理模式为其他对象提供一种代理以控制对这个对象的访问。(结构型模式)代理模式提供三种角色:

  • 抽象角色:声明真实对象和代理对象的共同接口。
  • 代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
  • 真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。 代理模式对外部提供统一的接口方法,而代理类在接口中实现对真实类的附加操作行为,从而可以在不影响外部调用情况下,进行系统扩展。

分类

静态代理

静态代理就是我们自己静态定义的代理类,例如我们要进行图片加载的时候,可以通过一个代理类减少图片对象加载的内存占用:

DEMO

图片接口

package factory.pattern.proxy.demo1;

/**
 * Created by FK on 2017/8/3.
 */
public interface Image {
    void dispalay();
}

接口实体类

package factory.pattern.proxy.demo1;

/**
 * Created by FK on 2017/8/3.
 */
public class RealImage implements Image {
    private String fileName;

    public RealImage(String fileName) {
        this.fileName = fileName;
        loadFormDisk(fileName);
    }

    private void loadFormDisk(String fileName) {
        System.out.println("Loading " + fileName);
    }

    @Override
    public void dispalay() {
        System.out.println("Displaying " + fileName);
    }
}

package factory.pattern.proxy.demo1;

/**
 * Created by FK on 2017/8/3.
 */
public class ProxyImage implements Image {
    private RealImage realImage;
    private String fileNmme;

    public ProxyImage(String fileNmme) {
        this.fileNmme = fileNmme;
    }

    @Override
    public void dispalay() {
        if( realImage == null){
            realImage = new RealImage(fileNmme);
        }
        realImage.dispalay();
    }
}

测试

package factory.pattern.proxy.demo1;

/**
 * Created by FK on 2017/8/3.
 */
public class Test {
    public static void main(String[] args) {
        Image image = new ProxyImage("test.jpg");
        image.dispalay();
        System.out.println();
        image.dispalay();
    }
}

动态代理

动态代理也需要实现接口,是利用JDK的API来实现代理对象的生成,所以动态代理也是JDK代理。

DEMO

package factory.pattern.proxy.demo2;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Created by FK on 2017/8/4.
 */
public class ProxyFactory {
    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    public Object getProxyInstance(){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object returnValue = method.invoke(target, args);
                        return returnValue;
                    }
                });
    }
}

测试

package factory.pattern.proxy.demo2;

import factory.pattern.proxy.demo1.Image;
import factory.pattern.proxy.demo1.RealImage;

/**
 * Created by FK on 2017/8/4.
 */
public class Test {
    public static void main(String[] args) {
        Image image = new RealImage("test1.jpg");
        System.out.println(image.getClass());
        Image proxy = (Image) new ProxyFactory(image).getProxyInstance();
        System.out.println(proxy.getClass());
        proxy.dispalay();
    }
}

应用场合

远程代理

就是为一个对象在不同的地址空间提供局部代表,这样可以隐藏一个对象存在不同地址空间的事实。

虚拟代理

根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。

html网页加载的时候图片是下载之后才能看到,未打开的图片框只存放了真实图片的路径和尺寸。

安全代理

安全代理用来控制真实对象访问时的权限。

智能指引

当调用真实的对象时,代理处理另外一些事。

计算真是对象的引用次数,当该对象没有引用时,可以自动释放它;或当第一次引用一个持久化对象,将它装载如内存。

#设计模式#
设计模式介绍 文章被收录于专栏

设计模式是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。其实就是经过前人反复使用总结使用得出在不同场景有对应的解决方案。

全部评论

相关推荐

球球别再泡了:坏,我单9要了14
点赞 评论 收藏
分享
2 2 评论
分享
牛客网
牛客企业服务