设计模式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的操作。

 

 

posted on 2014-11-28 17:45  Joyfulmath  阅读(185)  评论(0编辑  收藏  举报

导航