更多设计模式文章请阅读:

设计模式专栏

1.定义

为其他对象提供一种代理以控制对这个对象的直接控制

UML建模图.png

2.使用场景:

当无法或者直接访问到目标对象的时候,或者访问某个对象有困难的时候,可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象要实现相同的接口,即(代理和委托的约束)

3.代理模式分类

   分为两种:静态代理、动态代理。静态代理是由程序员创建或特定工具自动生成源代码,在对其编译。在程序员运行之前,代理类.class文件就已经被创建了。动态代理是在程序运行时通过反射机制动态创建的
3.1 静态代理模式
  • 简单实现
/**
 * 接口约束
 */
public abstract class Subject {

    //普通的业务方法
    abstract void visit();
}

  • 委托类
/**
 * 业务真实处理类
 */
public class RealSubject extends Subject {
    @Override
    void visit() {
        System.out.println("真正的实现方法");
    }
}
  • 代理类
/**
 * 代理类
 */
public class ProxySubject extends Subject {

    private  Subject mSubject;

    public ProxySubject(Subject subject) {
        this.mSubject=subject;
    }

    @Override
    void visit() {
        mSubject.visit();
    }
}
  • 项目中使用示例
    以Android工程示例,在项目开发中,前期使用的网络访问请求框架为volley,但是在项目迭代几个版本以后,发现使用volley框架,对大文件的下载支持不是很好(因为volley在下载文件的时候,目标文件有多大,直接创建一个和目标文件一样大小的文件,占用资源较大)这个时候,要求更换网络请求框架,如果这个时候,代码耦合度高的话,则使用到网络请求的地方,都会进行相应的修改,当然一个好的架构,会让切换框架变的非常简单。如下
public interface Ihttp {

    /**
     * GET 请求
     * @param url
     */
    void get(String url);

    /**
     * POST 请求
     * @param url
     * @param params
     */
    void post(String url,String params);
    
    //....

}

代理请求网络类

public class HttpProxy implements Ihttp {


    private void HttpProxy() {}

    public static HttpProxy mInstance;

    public static HttpProxy getInstance() {
        if (mInstance == null) {
            synchronized (HttpProxy.class) {
                if (mInstance == null)
                    mInstance = new HttpProxy();
            }
        }
        return mInstance;

    }


    private Ihttp mModle;

    public void setHttpModle(Ihttp modle) {
        this.mModle = modle;
    }
    

    @Override
    public void get(String url) {
        mModle.get(url);
    }

    @Override
    public void post(String url, String params) {
        mModle.post(url, params);
    }
}

okhttp访问网络框架

public class OkhttpModle implements Ihttp {
    @Override
    public void get(String url) {
        //模拟okhttp请求网络
        System.out.println("Okhttp request get()" + url);
    }

    @Override
    public void post(String url, String params) {
        System.out.println("Okhttp request post(params)" + url);
    }
}

volley访问网络框架

public class VolleyModle implements Ihttp {
    @Override
    public void get(String url) {
        //模拟Volley请求网络
        System.out.println("Volley request get()" +url);
    }

    @Override
    public void post(String url, String params) {
        System.out.println("Volley request post(params)" +url);
    }
}

项目初始化配置使用

public class Client {
    public static void main(String[] args){

        //如果使用volley请求框架
//        HttpProxy.getInstance().setHttpModle(new VolleyModle());

        //如果使用okhttp请求框架
        HttpProxy.getInstance().setHttpModle(new OkhttpModle());

        HttpProxy.getInstance().get("http://www.baidu.com");

    }
}

打印结果:

Okhttp request get()http://www.baidu.com
4.1 动态代理模式

定义:通过反射机制动态生成代理者对象,也就是说在code阶段不知道要代理谁,在执行阶段决定,java也提供了一个便捷的动态代理接口

/**
 * 接口约束
 */
public interface Subject {

    //普通的业务方法
     void visit();

}
/**
 * 业务真实处理类
 */
public class RealSubject implements Subject {
    @Override
    public void visit() {
        System.out.println("真正的实现方法");
    }
}
public class DynamicProxy implements InvocationHandler {


    private Object obj;

    public DynamicProxy(Object obj) {
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        Object invoke = method.invoke(obj, args);
        return invoke;
    }
}
public class Client {

    public static void main(String[] args){
        Subject subject=new RealSubject();
        DynamicProxy proxy = new DynamicProxy(subject);
        ClassLoader classLoader = subject.getClass().getClassLoader();

        Subject real = (Subject) Proxy.newProxyInstance(classLoader, new Class[]{Subject.class}, proxy);
        real.visit();
    }
}
Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐