• 【2016-10-11】【坚持学习】【Day2】【代理模式】


    今天学习了代理模式。

    • 定义

    官方:

    代理模式:给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问。

    Proxy Pattern: Provide a surrogate or placeholder for another object to control access to it.

    我的理解:

    原来是直接调用一个类的方法或者接口

    现在中间多了一个代理类,先调用代理类,再通过代理类里面调用原来真实的类。

    • 结构
    • 场景

    有以下几种代理模式:

    1、保护代理

    2、智能引用代理

        第一,第二种代理例子:

            原有系统:直接调用查询服务接口

            新需求:要验证用户是否登录成功(新)=》调用原有查询接口=》记录查询日志(新)

    class Proxy : Subject
    {
    private RealSubject realSubject = new RealSubject(); //维持一个对真实主题对象的引用
    public void PreRequest() 
    {
    …...
    }
    public override void Request() 
    {
    PreRequest();
        realSubject.Request(); //调用真实主题对象的方法
        PostRequest();
    }
    public void PostRequest() 
    {
    ……
    }
    }
    View Code

    3、远程代理(通过调用远程服务器实现业务)

    4、缓冲代理(查询很大的数据时候,可以保存在缓存中,下次调用就直接去缓存)

    public static class ProductDataProxy
    {
    private static readonly int productTimeout = int.Parse(ConfigurationManager.AppSettings ["ProductCacheDuration"]);
    private static readonly bool enableCaching = bool.Parse(ConfigurationManager. AppSettings["EnableCaching"]); 
    public static IList GetProductsByCategory(string category)
    {        
    Product product = new Product();
    //如果缓存被禁用,则直接通过product对象来获取数据
    if (!enableCaching)
    {
    return product.GetProductsByCategory(category);
    }
    string key = "product_by_category_" + category;
    //从缓存中获取数据
    IList data = (IList )HttpRuntime.Cache[key];  
    //如果缓存中没有数据则执行如下代码
    if (data == null)
    {            
    data = product.GetProductsByCategory(category);            
    //通过工厂创建AggregateCacheDependency对象
    AggregateCacheDependency cd = DependencyFacade.GetProductDependency (); 
    //将数据存储在缓存中,并添加必要的AggregateCacheDependency对象
    HttpRuntime.Cache.Add(key, data, cd, DateTime.Now.AddHours(product Timeout), Cache.NoSlidingExpiration, CacheItemPriority.High, null); 
    }
    return data;
    }
    ……
    }
    View Code

    5、虚拟代理

    书上解析:

    对于一些占用系统资源较多或者加载时间较长的对象,可以给这些对象提供一个虚拟代理
    在真实对象创建成功之前虚拟代理扮演真实对象的替身,而当真实对象创建之后,虚拟代理将用户的请求转发给真实对象
    使用一个“虚假”的代理对象来代表真实对象,通过代理对象来间接引用真实对象,可以在一定程度上提高系统的性能

     例子:

    CD封面:加载要好慢,那么先弄一个简单的出来,然后异步加载真实数据,并且呈现。

    //实现Icon接口  
    public class ImageProxy implements Icon {  
        ImageIcon imageIcon;  
        URL imageURL;  
        Thread retrievalThread;  
        boolean retrieving = false;  
      
        // 将图片的URL传入构造器中  
        public ImageProxy(URL url) {  
            imageURL = url;  
        }  
      
        // 在图像加载完毕前,返回默认的宽和高  
        // 图像加载完毕后,装给iamgeIcon处理  
        public int getIconWidth() {  
            if (imageIcon != null) {  
                return imageIcon.getIconWidth();  
            } else {  
                return 800;  
            }  
        }  
          
        public int getIconHeight() {  
            if (imageIcon != null) {  
                return imageIcon.getIconHeight();  
            } else {  
                return 600;  
            }  
        }  
      
        // 当要在屏幕上绘制图像时,就调用此方法  
        public void paintIcon(final Component c, Graphics g, int x, int y) {  
            // 如果已经有了icon,就画出  
            if (imageIcon != null) {  
                imageIcon.paintIcon(c, g, x, y);  
            } else {  
                // 还没有icon时,就显示“加载中...”的消息  
                g.drawString("CD封面加载中,请稍后...", x + 300, y + 190);  
                if (!retrieving) {  
                    retrieving = true;  
                      
                    // 在这个线程中加载真正的icon图像。注意,加载图像和ImageIcon是同步(synchronous)  
                    // 也就是说,只有在加载完之后,ImageIcon构造器才会返回。这样,我们的程序会耗在这里  
                    // 所以要把加载变成异步(asynchronous)的。  
                    retrievalThread = new Thread(new Runnable() {  
                        public void run() {  
                            try {  
                                imageIcon = new ImageIcon(imageURL, "CD Cover");  
                                c.repaint();  
                            } catch (Exception e) {  
                                e.printStackTrace();  
                            }  
                        }  
                    });  
                    retrievalThread.start();  
                }  
            }  
        }  
      
    }
    View Code

    作者:zscmj
    出处:http://www.cnblogs.com/zscmj/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    C# 进程间通信之二传递复杂数据类型(转)
    c# 进程间的通信实现之一简单字符串收发
    WinRAR压缩操作帮助类
    软件推荐:扫码格式检测系统
    C#位操作(转)
    浅析c#内存泄漏
    常用SQL语句
    linux下网站搭建
    VS中的活动debug和活动cpu
    让程序员跳槽的非钱原因
  • 原文地址:https://www.cnblogs.com/zscmj/p/5952840.html
Copyright © 2020-2023  润新知