码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式之代理模式---Proxy Pattern

时间:2016-08-08 21:12:47      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:

模式的定义

代理模式(Proxy Pattern)也叫做委托模式,定义如下:

Provide a surrogate or placeholder for another object to control access to is.

为其他对象提供一种代理以控制对这个对象的访问。

类型

结构类

模式的使用场景

想想现实世界中,打官司为什么要找个律师?因为你不想参与中间过程的是是非非,只要完成自己的工作就可以,其它的事情比如事前调查,事后追查都可以由律师来负责,这就可以减少你的负担。代理模式使用的场景 非常多。

UML类图

角色介绍

Subject–抽象主题角色
抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义

RealSubject—具体主题角色
也叫做被委托角色,被代理角色。是业务逻辑的具体执行者

Proxy—-代理主题角色
也叫委托类,代理类。它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。

模式的通用源码

Subject—-抽象主题类:


public interface Subject {

    public void request();
}

RealSubject—-真实主题类:


public class RealSubject implements Subject {

    @Override
    public void request() {
        // TODO Auto-generated method stub
        System.out.println("RealSubject---request");
    }

}

Proxy—代理类:


public class Proxy implements Subject {

    private Subject subject;

    public Proxy(){
        this.subject = new Proxy();
    }

    public Proxy(Object... objects){

    }

    public Proxy(Subject subject){
        this.subject = subject;
    }

    @Override
    public void request() {
        // TODO Auto-generated method stub
        this.before();
        this.subject.request();
        this.after();
    }

    private void after() {
        // TODO Auto-generated method stub
        System.out.println("Proxy---after");
    }

    private void before() {
        // TODO Auto-generated method stub
        System.out.println("Proxy---before");
    }

}

Client类:

public class Client {


    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Subject subject = new RealSubject();
        Proxy proxy = new Proxy(subject);
        proxy.request();
    }

}

输出结果:

Proxy---before
RealSubject---request
Proxy---after

优点

  • 职责清晰

    真实的角色就是实现实际的业务逻辑,不用关心其它的非本职责的事务,通过后期的代理完成一件事务,附带的结果是编程简洁清晰

  • 高扩展性

    具体的主题角色是随时都会发生变化,只要它实现了接口,甭管它如何变化,都逃不脱如来的手掌(接口),那我们的代理类完全就可以在不做任何修改的情况下使用。

  • 智能化

    这主要体现在动态代理上。

Android源码中的模式实现

android Proxy样例一

抽象对象类—ProxySelector:

./libcore/luni/src/main/java/java/net/ProxySelector.java
public abstract class ProxySelector {
   ......
   private static ProxySelector defaultSelector = new ProxySelectorImpl();
   ......
   public abstract List<Proxy> select(URI uri);
   public abstract void connectFailed(URI uri, SocketAddress address, IOException failure);
}

具体对象类—-PacProxySelector:

./frameworks/base/core/java/android/net/PacProxySelector.java

关键代码:

public class PacProxySelector extends ProxySelector {

    ......
    private IProxyService mProxyService;
    private final List<Proxy> mDefaultList;
    ......
    @Override
    public List<Proxy> select(URI uri) {
        if (mProxyService == null) {
            mProxyService = IProxyService.Stub.asInterface(
                    ServiceManager.getService(PROXY_SERVICE));
        }
        if (mProxyService == null) {
            Log.e(TAG, "select: no proxy service return NO_PROXY");
            return Lists.newArrayList(java.net.Proxy.NO_PROXY);
        }
        String response = null;
        String urlString;
        try {
            urlString = uri.toURL().toString();
        } catch (MalformedURLException e) {
            urlString = uri.getHost();
        }
        try {
            response = mProxyService.resolvePacFile(uri.getHost(), urlString);
        } catch (Exception e) {
            Log.e(TAG, "Error resolving PAC File", e);
        }
        if (response == null) {
            return mDefaultList;
        }

        return parseResponse(response);
    }

    ......
    @Override
    public void connectFailed(URI uri, SocketAddress address, IOException failure) {

    }
    ......
}

代理类—-Proxy:

./frameworks/base/core/java/android/net/Proxy.java
public final class Proxy {
   ......
   private static final ProxySelector sDefaultProxySelector;
   ......
   public static final void setHttpProxySystemProperty(String host, String port, String exclList,
            Uri pacFileUrl) {
        ......
        if (!Uri.EMPTY.equals(pacFileUrl)) {
            ProxySelector.setDefault(new PacProxySelector());
        } else {
            ProxySelector.setDefault(sDefaultProxySelector);
        }
    }


}

android Proxy样例二

抽象对象类—Thread:

具体对象类—-ProxyServer:

./frameworks/base/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java

关键代码:

public class ProxyServer extends Thread {
    ......
    @Override
    public void run() {
        try {
            serverSocket = new ServerSocket(0);

            setPort(serverSocket.getLocalPort());

            while (mIsRunning) {
                try {
                    Socket socket = serverSocket.accept();
                    // Only receive local connections.
                    if (socket.getInetAddress().isLoopbackAddress()) {
                        ProxyConnection parser = new ProxyConnection(socket);

                        threadExecutor.execute(parser);
                    } else {
                        socket.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (SocketException e) {
            Log.e(TAG, "Failed to start proxy server", e);
        } catch (IOException e1) {
            Log.e(TAG, "Failed to start proxy server", e1);
        }

        mIsRunning = false;
    }

}

代理类—-ProxyService:

./frameworks/base/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java
public class ProxyService extends Service {

    private static ProxyServer server = null;
`
    @Override
    public void onCreate() {
        super.onCreate();
        if (server == null) {
            server = new ProxyServer();
            server.startServer();
        }
    }
......
}

参考资料

(1).设计模式之禅—第12章 代理模式
(2)代理模式
https://github.com/simple-android-framework/android_design_patterns_analysis/tree/master/proxy/singwhatiwanna

设计模式之代理模式---Proxy Pattern

标签:

原文地址:http://blog.csdn.net/hfreeman2008/article/details/52153658

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!