首页 > 代码库 > 设计模式6---代理模式

设计模式6---代理模式

  代理模式的核心其实就是在 上层代码和framework层代码之间增加一个中间层。

  从而对于核心代码来说,对于上层是透明的。

  使用代理模式可以很好的,剪切核心代码功能,或者扩展功能已符合上层代码的使用。

  已一个开关camera的例子来演示代理模式:

  1.对于上层来说,并不关心camera的类型,焦距之类的,只要有开关就可以了。

  2.对于具体的camera类来说,它有很多功能可以设置。

  UML图:

 

  camera操作接口:

public interface ICameraOperator {    boolean open();    void close();}

camera抽象实现类:

public abstract class BasicCamera {        private String name = null;        public BasicCamera(String name)    {        this.name = name;    }        public boolean open()    {        System.out.println(name+" camera"+" open");        return true;            }        public void close()    {        System.out.println(name+" camera"+" close");    }        }

所有camera都实现上述类,而代理只需要调用BasicCamera 的open和close就可以实现对实际camera的操作。

import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;public class ProxyCamera implements ICameraOperator {    private static final String AssemblyName = "com.jayfulmath.designpattern.proxy";    private static final String DefaultCamera = "YUUCamera";    private String CameraString = null;    BasicCamera camera = null;        private static ProxyCamera _mInstance = null;        public static ProxyCamera getInstance()    {        if(_mInstance == null)        {            _mInstance = new ProxyCamera();        }        return _mInstance;    }            public ProxyCamera() {        IXmlParse parse = new XmlParse("src/com/jayfulmath/designpattern/proxy/CameraConfig.xml");        CameraString = parse.parseXmlValue("camera");        if(CameraString == null)        {            CameraString = DefaultCamera;        }        String className = AssemblyName + "." + CameraString;        Class<?> c;        try {            c = Class.forName(className);            Constructor<?> ct = c.getConstructor();            camera = (BasicCamera) (ct.newInstance());        } catch (ClassNotFoundException | NoSuchMethodException                | SecurityException | InstantiationException                | IllegalAccessException | IllegalArgumentException                | InvocationTargetException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    @Override    public boolean open() {        boolean result = false;        if (camera != null) {            result = camera.open();        }        return result;    }    @Override    public void close() {        if (camera != null) {            camera.close();        }    }}

此处camera的配置用到了反射和xml配置文件,从而,我们只需要在xml里面配置具体的camera就可以实现对camera使用的切换,

而上层则根本不需要知道调用哪个camera.

import java.io.File;import java.io.IOException;import java.util.HashMap;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xml.sax.SAXException;public class XmlParse implements IXmlParse {    private String xmlPath = null;    DocumentBuilderFactory builderFactory = DocumentBuilderFactory            .newInstance();        public HashMap<String, String> mNode = new HashMap();        public XmlParse(String path) {        xmlPath = path;        mNode.clear();        init();    }    public void init() {        Document doc = parse(xmlPath);        Element rootElement = doc.getDocumentElement();        // traverse child elements        NodeList nodes = rootElement.getElementsByTagName("key");        for (int i = 0; i < nodes.getLength(); i++) {            Node node = nodes.item(i);            if (node.getNodeType() == Node.ELEMENT_NODE) {                Element child = (Element) node;                if(child.getAttribute("name") != null)                {                    mNode.put(child.getAttribute("name"), child.getTextContent());                }            }        }    }    // Load and parse XML file into DOM    public Document parse(String filePath) {        Document document = null;        try {            // DOM parser instance            DocumentBuilder builder = builderFactory.newDocumentBuilder();            // parse an XML file into a DOM tree            document = builder.parse(new File(filePath));        } catch (ParserConfigurationException e) {            e.printStackTrace();        } catch (SAXException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        return document;    }    @Override    public String parseXmlValue(String name) {        String result = null;        if(mNode!=null && mNode.size()>0)        {            if(mNode.containsKey(name))            {                result = mNode.get(name);            }        }        return result;    }}
public interface IXmlParse {    String parseXmlValue(String name);}

xml 解析和解析接口。

最后就是main方法:

package com.jayfulmath.designpattern.proxy;import com.jayfulmath.designpattern.main.BasicExample;public class ProxyMain extends BasicExample {    @Override    public void startDemo() {        ProxyCamera mCamera = ProxyCamera.getInstance();        mCamera.open();        mCamera.close();    }}

 

代理模式主要目的就是通过代理,而使实际下层操作类对上层界面的透明。并且proxy可以根据情况适当的裁剪和扩展实际下层camera的操作。

 

 

设计模式6---代理模式