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

     

  • 相关阅读:
    CocoaPods版本升级
    NSParameterAssert
    layoutSubviews在以下情况下会被调用:
    swift笔记
    提交app时候90475,90474
    大数据基础---Azkaban_Flow_1.0_的使用
    大数据基础---Azkaban_3.x_编译及部署
    大数据基础---Azkaban简介
    大数据基础---Scala隐式转换和隐式参数
    大数据基础---Scala类型参数
  • 原文地址:https://www.cnblogs.com/deman/p/4129103.html
Copyright © 2020-2023  润新知