首页 > 代码库 > 设计模式完结(12)-- 代理模式

设计模式完结(12)-- 代理模式

代理模式与装饰模式区别:

装饰器模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。换句话说,用代理模式,代理类(proxy class)可以对它的客户隐藏一个对象的具体信息。

因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。并且,当我们使用装饰器模 式的时候,我们通常的做法是将原始对象作为一个参数传给装饰者的构造器。

我们可以用另外一句话来总结这些差别:使用代理模式,代理和真实对象之间的的关系通常在编译时就已经确定了,而装饰者能够在运行时递归地被构造。    

 

//代理模式
public class Proxy implements Subject{

       private Subject subject;
       public Proxy(){
             //关系在编译时确定
            subject = new RealSubject();
       }
       public void doAction(){
             ….
             subject.doAction();
             ….
       }
}
//代理的客户
public class Client{
        public static void main(String[] args){
             //客户不知道代理委托了另一个对象
             Subject subject = new Proxy();
             …
        }
}

技术分享 

 

 

代理模式:

是一种对象结构型模式。在代理模式中引入了一个新的代理对象,代理对象在客户端对象和目标对象之间起到中介的作用,它去掉客户不能看到的内容和服务或者增添客户需要的额外的新服务。

实例:

 

 

技术分享

 

//AccessValidator.cs  
using System;  

namespace ProxySample  
{  
    class AccessValidator  
    {  
        //模拟实现登录验证  
        public bool Validate(string userId)   
        {  
            Console.WriteLine("在数据库中验证用户‘" + userId + "‘是否是合法用户?");  
            if (userId.Equals("杨过")) {  
                Console.WriteLine("‘{0}‘登录成功!",userId);  
                return true;  
            }  
            else {  
                Console.WriteLine("‘{0}‘登录失败!", userId);  
                return false;  
            }  
        }  
    }  
}
//Logger.cs  
using System;  

namespace ProxySample  
{  
    class Logger  
    {  
        //模拟实现日志记录  
        public void Log(string userId) {  
            Console.WriteLine("更新数据库,用户‘{0}‘查询次数加1!",userId);  
        }  
    }  
}
//Searcher.cs  
namespace ProxySample  
{  
    interface Searcher  
    {  
        string DoSearch(string userId, string keyword);  
    }  
}
//RealSearcher.cs  
using System;  

namespace ProxySample  
{  
    class RealSearcher : Searcher  
    {  
        //模拟查询商务信息  
        public string DoSearch(string userId, string keyword) {  
            Console.WriteLine("用户‘{0}‘使用关键词‘{1}‘查询商务信息!",userId,keyword);  
            return "返回具体内容";  
        }  
    }  
}
//ProxySearcher.cs  
namespace ProxySample  
{  
    class ProxySearcher : Searcher  
    {  
        private RealSearcher searcher = new RealSearcher(); //维持一个对真实主题的引用  
        private AccessValidator validator;  
        private Logger logger;  

        public string DoSearch(string userId, string keyword)  
        {  
            //如果身份验证成功,则执行查询  
            if (this.Validate(userId))  
            {  
                string result = searcher.DoSearch(userId, keyword); //调用真实主题对象的查询方法  
                this.Log(userId); //记录查询日志  
                return result; //返回查询结果  
            }  
            else  
            {  
                return null;  
            }  
        }  

        //创建访问验证对象并调用其Validate()方法实现身份验证  
        public bool Validate(string userId)  
        {  
            validator = new AccessValidator();  
            return validator.Validate(userId);  
        }  

        //创建日志记录对象并调用其Log()方法实现日志记录  
        public void Log(string userId)  
        {  
            logger = new Logger();  
            logger.Log(userId);  
        }  
    }  
}

在代理类ProxySearcher中实现对真实主题类的权限控制和引用计数.

15.7 代理模式效果与适用场景
代理模式是常用的结构型设计模式之一,它为对象的间接访问提供了一个解决方案,可以对对象的访问进行控制。代理模式类型较多,其中远程代理、虚拟代理、保护代理等在软件开发中应用非常广泛。

 

 

15.7.3 模式适用场景
代理模式的类型较多,不同类型的代理模式有不同的优缺点,它们应用于不同的场合:

(1) 当客户端对象需要访问远程主机中的对象时可以使用远程代理。

(2) 当需要用一个消耗资源较少的对象来代表一个消耗资源较多的对象,从而降低系统开销、缩短运行时间时可以使用虚拟代理,例如一个对象需要很长时间才能完成加载时。
(3) 当需要为某一个被频繁访问的操作结果提供一个临时存储空间,以供多个客户端共享访问这些结果时可以使用缓冲代理。通过使用缓冲代理,系统无须在客户端每一次访问时都重新执行操作,只需直接从临时缓冲区获取操作结果即可。
(4) 当需要控制对一个对象的访问,为不同用户提供不同级别的访问权限时可以使用保护代理。
(5) 当需要为一个对象的访问(引用)提供一些额外的操作时可以使用智能引用代理。

Java的三种代理模式

http://www.cnblogs.com/cenyu/p/6289209.html

设计模式完结(12)-- 代理模式