zoukankan      html  css  js  c++  java
  • C#设计模式系列:代理模式(Proxy)

      代理模式提供了一个中介控制对某个对象的访问。现实生活中,我们可能会用支票在市场交易中用来代替现金,支票就是账户中资金的代理。

    1、代理模式简介

    1.1>、定义  

      代理模式(Proxy)定义:代理模式为客户端程序提供一种中间层以控制对这个对象的访问。

    1.2>、使用频率

       中高

    2、代理模式结构

    2.1>、结构图

    2.2>、参与者

      代理模式参与者:

      ◊ Proxy

        ° 维持一个引用,使得代理可以访问Subject。

        ° 提供一个与Subject的接口相同的接口,这样代理就可以替代Subject。

        ° 控制对Subject的访问,并可能负责对Subject的创建和删除。

      ◊ Subject:定义ConcreteSubject与Proxy的共用接口,从而在任何使用ConcreteSubject的地方都可以使用Proxy。

      ◊ ConcreteSubject:定义Proxy所代表的Subject。

      ◊ Client:维持一个对Subject的引用

      在代理模式中,由于Proxy与ConcreteSubject继承同一接口,所以Client调用ConcreteSubject可以转化为Client调用Proxy在调用ConcreteSubject,类Proxy为中间代理。

    3、代理模式结构实现

      Subject.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace DesignPatterns.ProxyPattern.Structural
    {
        public abstract class Subject
        {
            public abstract void Request();
        }
    }

      ConcreteSubject.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace DesignPatterns.ProxyPattern.Structural
    {
        public class ConcreteSubject : Subject
        {
            public override void Request()
            {
                Console.WriteLine("Called ConcreteSubject.Request()");
            }
        }
    }

      Proxy.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace DesignPatterns.ProxyPattern.Structural
    {
        public class Proxy : Subject
        {
            private ConcreteSubject _concreteSubject;
    
            public override void Request()
            {
                // Use 'lazy initialization'
                if (_concreteSubject == null)
                {
                    _concreteSubject = new ConcreteSubject();
                }
    
                _concreteSubject.Request();
            }
        }
    }

      Program.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using DesignPatterns.ProxyPattern.Structural;
    
    namespace DesignPatterns.ProxyPattern
    {
        class Program
        {
            static void Main(string[] args)
            {
                // Create proxy and request a service
                Proxy proxy = new Proxy();
                proxy.Request();
            }
        }
    }

      运行输出:

    Called ConcreteSubject.Request()
    请按任意键继续. . .

    4、代理模式实践应用

      IMath.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace DesignPatterns.ProxyPattern.Practical
    {
        /// <summary>
        /// The 'Subject interface
        /// </summary>
        public interface IMath
        {
            double Add(double x, double y);
            double Sub(double x, double y);
            double Mul(double x, double y);
            double Div(double x, double y);
        }
    }

      Math.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace DesignPatterns.ProxyPattern.Practical
    {
        /// <summary>
        /// The 'ConcreteSubject' class
        /// </summary>
        public class Math : IMath
        {
            public double Add(double x, double y)
            {
                return x + y;
            }
            public double Sub(double x, double y)
            {
                return x - y;
            }
            public double Mul(double x, double y)
            {
                return x * y;
            }
            public double Div(double x, double y)
            {
                return x / y;
            }
        }
    }

      MathProxy.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace DesignPatterns.ProxyPattern.Practical
    {
        public class MathProxy : IMath
        {
            private Math _math = new Math();
    
            public double Add(double x, double y)
            {
                return _math.Add(x, y);
            }
    
            public double Sub(double x, double y)
            {
                return _math.Sub(x, y);
            }
    
            public double Mul(double x, double y)
            {
                return _math.Mul(x, y);
            }
    
            public double Div(double x, double y)
            {
                return _math.Div(x, y);
            }
        }
    }

      Program.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using DesignPatterns.ProxyPattern.Practical;
    
    namespace DesignPatterns.ProxyPattern
    {
        class Program
        {
            static void Main(string[] args)
            {
                // Create math proxy
                MathProxy proxy = new MathProxy();
    
                // Do the math
                Console.WriteLine("4 + 2 = " + proxy.Add(4, 2));
                Console.WriteLine("4 - 2 = " + proxy.Sub(4, 2));
                Console.WriteLine("4 * 2 = " + proxy.Mul(4, 2));
                Console.WriteLine("4 / 2 = " + proxy.Div(4, 2));
            }
        }
    }

      运行输出:

    4 + 2 = 6
    4 - 2 = 2
    4 * 2 = 8
    4 / 2 = 2
    请按任意键继续. . .

    5、代理模式应用分析

      代理模式适用范围很广,不同的代理适合于不同的情形。

      ◊ 远程代理为一个对象在不同的地址空间提供局部代表。

      ◊ 虚代理在需要创建开销很大的对象时缓存对象信息。

      ◊ 保护代理控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。

      ◊ 智能指引取代了简单指引,它在访问对象时执行了一些附加操作。它的典型用途包括:对指向实际对象的引用计数,这样当该对象没有引用时,可以自动释放。当第一次引用一个持久对象时,将它装入内存。在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能改变它。

      代理模式特点:

      ◊ 代理模式在访问对象时引入一定程度的间接性,可以隐藏对象的位置。

      ◊ 代理模式可以对用户隐藏一种称之为copy-on-write的优化方式。当进行一个开销很大的复制操作的时候,如果复制没有被修改,则代理延迟这一复制过程,这一可以保证只有当这个对象被修改的时候才对它进行复制。

    6、代理模式与装饰模式比较分析

      装饰器模式关注于在一个对象上动态的添加方法,代理模式关注于控制对对象的访问。

      装饰器模式中Decorator和ConcreteComponent都实现Component,代理模式中Proxy和ConcreteSubject都实现Subject。使用这两种模式,都可以很容易地在具体对象的方法前面或者后面加上自定义的方法。

      Proxy 可以对Client隐藏对象的具体信息,在使用代理模式时,常在Proxy中创建一个对象的实例。Proxy与ConcreteSubject之间的关系在编译时就能确定。
      在使用装饰模式时,常是将ConcreteComponent对象作为一个参数传给ConcreteDecorator的构造器,Decorator在运行时递归的被构造。

  • 相关阅读:
    telent connection refused
    (待整理)flume操作----------hivelogsToHDFS案例----------运行时,发生NoClassDefFoundError错误
    Java核心技术36讲----------Exception和Error有什么区别
    Hive操作之向分区表中导入数据的语义错误
    java的值传递机制
    notepad无法对linux中的文件进行修改???
    读书笔记----------第五章----------字符串
    读书笔记----------第四章----------流程控制
    java中子类会继承父类的构造方法吗?
    文章分类
  • 原文地址:https://www.cnblogs.com/libingql/p/3637660.html
Copyright © 2011-2022 走看看