C#设计模式之十二代理模式(Proxy Pattern)【结构型】

一、引言

   今天我们要讲【结构型】设计模式的第七个模式,也是“结构型”设计模式中的最后一个模式,该模式是【代理模式】,英文名称是:Proxy Pattern。还是老套路,先从名字上来看看。“代理”可以理解为“代替”,代替“主人”做一些事情,为什么需要“代理”,是因为某些原因(比如:安全方面的原因),不想让“主人”直接面对这些繁琐、复杂的问题,但是这些事情是经“主人”同意或者授意的,如同“主人”亲自完成的一样。这个模式很简单,生活中的例子也很多。举例说明,歌星、影星的经纪人就是现实生活中一个代理模式的很好例子,还有操作系统中的防火墙,也是代理的例子,要访问系统,先过防火墙这关,否则免谈。还有很多了,就不一一列举了,大家在生活中慢慢的体会吧。

二、代理模式的详细介绍

2.1、动机(Motivate)

   在面向对象系统中,有些对象由于某种原因(比如对象创建的开销很大,或者某些操作需要安全控制,或者需要进程外的访问等),直接访问会给使用者、或者系统结构带来很多麻烦。如何在不失去透明操作对象的同时来管理/控制这些对象特有的复杂性?增加一层间接层是软件开发中常见的解决方式。

2.2、意图(Intent)

   为其他对象提供一种代理以控制对这个对象的访问。                                      ——《设计模式》GoF

2.3、结构图(Structure)

     

2.4、模式的组成
    
    代理模式所涉及的角色有三个:

    (1)、抽象主题角色(Subject):声明了真实主题和代理主题的公共接口,这样一来在使用真实主题的任何地方都可以使用代理主题。

    (2)、代理主题角色(Proxy):代理主题角色内部含有对真实主题的引用,从而可以操作真实主题对象;代理主题角色负责在需要的时候创建真实主题对象;代理角色通常在将客户端调用传递到真实主题之前或之后,都要执行一些其他的操作,而不是单纯地将调用传递给真实主题对象。

    (3)、真实主题角色(RealSubject):定义了代理角色所代表的真实对象。

    附:在WCF或者WebService的开发过程中,我们在客户端添加服务引用的时候,在客户程序中会添加一些额外的类,在客户端生成的类扮演着代理主题角色,我们客户端也是直接调用这些代理角色来访问远程服务提供的操作。这个是远程代理的一个典型例子。

2.5、代理模式的分类:

    代理模式按照使用目的可以分为以下几种:

    (1)、远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是本电脑中,也可以在另一台电脑中。最典型的例子就是——客户端调用Web服务或WCF服务。

    (2)、虚拟(Virtual)代理:根据需要创建一个资源消耗较大的对象,使得对象只在需要时才会被真正创建。

    (3)、Copy-on-Write代理:虚拟代理的一种,把复制(或者叫克隆)拖延到只有在客户端需要时,才真正采取行动。

    (4)、保护(Protect or Access)代理:控制一个对象的访问,可以给不同的用户提供不同级别的使用权限。

    (5)、防火墙(Firewall)代理:保护目标不让恶意用户接近。

    (6)、智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。

    (7)、Cache代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以这些结果。

   在上面所有种类的代理模式中,虚拟代理、远程代理、智能引用代理和保护代理较为常见的代理模式。

2.6、代理模式的具体实现

    说起“代理模式”,其实很容易,现实生活中的例子也很多。明星的经纪人,国家的发言人都是代理的好例子。我们就用明星经纪人这个事情来介绍“代理模式”的实现吧。

 1 namespace 代理模式的实现
 2 {
 3     /// <summary>
 4     /// 大明星都有钱,有钱了,就可以请自己的经纪人了,有了经纪人,很多事情就不用自己亲力亲为。弄点绯闻,炒作一下子通过经纪人就可以名正言顺的的操作了,万一搞不好,自己也可以否认。
 5     /// </summary>
 6     class Client
 7     {
 8         static void Main(string[] args)
 9         {
10             //近期,Fan姓明星关注度有点下降,来点炒作
11             AgentAbstract fan = new AgentPerson();
12             fan.Speculation("偶尔出来现现身,为炒作造势");
13 
14             Console.WriteLine();
15 
16             //过了段时间,又不行了,再炒作一次
17             fan.Speculation("这段时间不火了,开始离婚炒作");
18 
19 
20             Console.Read();
21         }
22     }
23 
24 
25     //该类型就是抽象Subject角色,定义代理角色和真实主体角色共有的接口方法
26     public abstract class AgentAbstract
27     {
28 
29         //该方法执行具体的炒作---该方法相当于抽象Subject的Request方法
30         public virtual void Speculation(string thing)
31         {
32             Console.WriteLine(thing);
33         }
34     }
35 
36     //该类型是Fan姓明星,有钱有势,想炒什么炒什么---相当于具体的RealSubject角色
37     public sealed class FanStar : AgentAbstract
38     {
39         //有钱有势,有背景啊
40         public FanStar() { }
41 
42         //要有名气,定期要炒作---就是RealSubject类型的Request方法
43         public override void Speculation(string thing)
44         {
45             Console.WriteLine(thing);
46         }
47     }
48 
49     //该类型是代理类型----相当于具体的Proxy角色
50     public sealed class AgentPerson : AgentAbstract
51     {
52         //这是背后的老板,
53         private FanStar boss;
54 
55         //老板在后面发号施令
56         public AgentPerson()
57         {
58             boss = new FanStar();
59         }
60 
61         //炒作的方法,执行具体的炒作---就是Proxy类型的Request方法
62         public override void Speculation(string thing)
63         {
64             Console.WriteLine("前期弄点绯闻,拍点野照");
65             base.Speculation(thing);
66             Console.WriteLine("然后开发布会,伤心哭泣,继续捞钱");
67         }
68     }
69 }


   这个模式很简单,就话不多说了。

三、代理模式的实现要点:
    
    “增加一层间接层”是软件系统中对许多复杂问题的一种常见解决方法。在面向对象系统中,直接使用某些对象会来带很多问题,作为间接层的Proxy对象便是解决这一问题的常用手段。具体Proxy设计模式的实现方法、实现粒度都相差很大,有些可能对单个对象做细粒度的控制,如copy-on-write技术,有些可能对组件模块提供抽象代理层,在架构层次对对象做Proxy。

  Proxy并不一定要求保持接口的一致性,只要能够实现间接控制,有时候损及一些透明性是可以接受的。

    3.1】、代理模式的优点:

          (1)、代理模式能够将调用用于真正被调用的对象隔离,在一定程度上降低了系统的耦合度;

          (2)、代理对象在客户端和目标对象之间起到一个中介的作用,这样可以起到对目标对象的保护。代理对象可以在对目标对象发出请求之前进行一个额外的操作,例如权限检查等。

           不同类型的代理模式也具有独特的优点,例如:

         (1)、远程代理为位于两个不同地址空间对象的访问提供了一种实现机制,可以将一些消耗资源较多的对象和操作移至性能更好的计算机上,提高系统的整体运行效率。

         (2)、虚拟代理通过一个消耗资源较少的对象来代表一个消耗资源较多的对象,可以在一定程度上节省系统的运行开销。

         (3)、缓冲代理为某一个操作的结果提供临时的缓存存储空间,以便在后续使用中能够共享这些结果,优化系统性能,缩短执行时间。

         (4)、保护代理可以控制对一个对象的访问权限,为不同用户提供不同级别的使用权限。

    3.2】、代理模式的缺点:

          (1)、由于在客户端和真实主题之间增加了一个代理对象,所以会造成请求的处理速度变慢

          (2)、实现代理类也需要额外的工作,从而增加了系统的实现复杂度。

    3.3】、代理模式的使用场景:

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

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

            (2)、当需要用一个消耗资源较少的对象来代表一个消耗资源较多的对象,从而降低系统开销、缩短运行时间时可以使用虚拟代理,例如一个对象需要很长时间才能完成加载时。

            (3)、当需要为某一个被频繁访问的操作结果提供一个临时存储空间,以供多个客户端共享访问这些结果时可以使用缓冲代理。通过使用缓冲代理,系统无须在客户端每一次访问时都重新执行操作,只需直接从临时缓冲区获取操作结果即可。

            (4)、 当需要控制对一个对象的访问,为不同用户提供不同级别的访问权限时可以使用保护代理

            (5)、当需要为一个对象的访问(引用)提供一些额外的操作时可以使用智能引用代理

四、.NET 中代理模式的实现

    代理模式在Net的FCL中的实现也不少,框架级别的有,类级别的也有。框架级别的有WCF,Remoting,他们都需要生成本地的代理,然后通过代理访问进程外或者机器外的对象。类级别的有StringBuilder类型,StringBuilder其实就是一种代理,我们本意是想访问字符串的,StringBuilder就是一种可变字符串的代理,而且StringBuilder也没有和String保持接口的一致性。

五、总结

      到今天为止,我们设计模式的三个部分讲完两个部分了,第一个部分是“创建型”的设计模式,解决对象创建的问题,对对象创建的解耦。第二部分就是“结构型”的设计模式,所谓结构型设计模式模式,顾名思义讨论的是类和对象的结构 ,主要用来处理类或对象的组合。它包括两种类型,一是类结构型模式,指的是采用继承机制来组合接口或实现;二是对象结构型模式,指的是通过组合对象的方式来实现新的功能。它包括适配器模式、桥接模式、装饰者模式、组合模式、外观模式、享元模式和代理模式。设计模式到现在也说了不少了,但是看起来很多模式都很类似,之间好像很容转换,有时候条件不同了,的确模式也可以转换,但是不能肆意的转换。为了避免思想的混乱,我们把“结构型”这个几个设计模式,再总结一次,把握核心,理解使用场景。

    适配器模式注重转换接口,将不吻合的接口适配对接

    桥接模式注重分离接口与其实现,支持多维度变化

    组合模式注重统一接口,将“一对多”的关系转化为“一对一”的关系

    装饰者模式注重稳定接口,在此前提下为对象扩展功能

    外观模式注重简化接口,简化组件系统与外部客户程序的依赖关系

    享元模式注重保留接口,在内部使用共享技术对对象存储进行优化

    代理模式注重假借接口,增加间接层来实现灵活控制

  从下篇文章就开始写“行为型”设计模式,今天就到此结束了。

转载于:https://www.cnblogs.com/PatrickLiu/p/7814004.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/252939.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CentOS7.5 使用二进制程序部署Kubernetes1.12.2(三)

一、安装方式介绍 1、yum 安装 目前CentOS官方已经把Kubernetes源放入到自己的默认 extras 仓库里面&#xff0c;使用 yum 安装&#xff0c;好处是简单&#xff0c;坏处也很明显&#xff0c;需要官方更新 yum 源才能获得最新版本的软件&#xff0c;而所有软件的依赖又不能自己指…

马来西亚热情拥抱阿里巴巴 马云倡议的eWTP首次落地海外

摘要&#xff1a;3月22日&#xff0c;马来西亚总理纳吉布与阿里巴巴集团董事局主席马云一同出现在吉隆坡一场盛大启动仪式上&#xff0c;他们将共同见证马云的eWTP理念落地马来西亚。 3月22日&#xff0c;在邀请阿里巴巴集团董事局主席马云、阿里巴巴集团CEO张勇、蚂蚁金服集团…

随便玩玩之PostgreSQL(第一章)PostgreSQL简介

随便玩玩之PostgreSQL 未经授权不得转载 第1章PostgreSQL简介 1.1什么是PostgreSQLPostgresql是数据库&#xff08;软件&#xff09;。The worlds most advanced open source database.世界上最先进的开源数据库。 1.2PostgreSQL的优势随便用、不要钱 比MySQL好&#xff0c;媲美…

生产环境中Oracle常用函数总结

1>to_char,将日期转换为字符&#xff1b;add_months,在第一个参数的日期上加或者减第二个参数的值&#xff1b;select dkzh,jkhtbh,yhkrq,dkffrq,shqs,dqyqcs,to_char(add_months(dkffrq,shqsdqyqcs1),yyyymm) from grdk_dk_zz a where a.dkzt in(02,03) and jgbm like 01||…

Dockerfile构建容器镜像 - 运维笔记

在Docker的运用中&#xff0c;从下载镜像&#xff0c;启动容器&#xff0c;在容器中输入命令来运行程序&#xff0c;这些命令都是手工一条条往里输入的&#xff0c;无法重复利用&#xff0c;而且效率很低。所以就需要一 种文件或脚本&#xff0c;我们把想执行的操作以命令的方式…

201421123042 《Java程序设计》第8周学习总结

1. 本周学习总结 以你喜欢的方式&#xff08;思维导图或其他&#xff09;归纳总结集合相关内容。 2. 书面作业 1. ArrayList代码分析 1.1 解释ArrayList的contains源代码 源代码&#xff1a; 答&#xff1a;查找对象是否再数组中&#xff0c;并且返回在数组中的下标。如果不在数…

Linux学习-11月12日(Apache安装)

2019独角兽企业重金招聘Python工程师标准>>> 11.6 MariaDB安装 11.7/11.8/11.9 Apache安装 扩展 apache dso https://yq.aliyun.com/articles/6298 apache apxs https://wizardforcel.gitbooks.io/apache-doc/content/51.html apache工作模式 https://blog.csdn.…

Linux C 读取文件夹下所有文件(包括子文件夹)的文件名

本文&#xff1a;http://www.cnblogs.com/xudong-bupt/p/3504442.html Linux C 下面读取文件夹要用到结构体struct dirent&#xff0c;在头#include <dirent.h>中&#xff0c;如下&#xff1a; #include <dirent.h> struct dirent {long d_ino; /* inode number 索…

报表工具实现单据套打

【摘要】 单据套打再也不用手动测量&#xff0c;反复调试了&#xff0c;报表工具实现单据套打&#xff0c;去乾学院看个究竟&#xff1a;报表工具实现单据套打!实际项目开发中&#xff0c;很多情况会涉及到单据的打印。即在一张印刷好的空白单据上&#xff0c;准确无误地打印上…

session机制详解以及session的相关应用

session是web开发里一个重要的概念&#xff0c;在大多数web应用里session都是被当做现成的东西&#xff0c;拿来就直接用&#xff0c;但是一些复杂的web应用里能拿来用的session已经满足不了实际的需求&#xff0c;当碰到这样的情况时候我们需要更加深入的理解session的机制&am…

(转)Shell中获取字符串长度的七种方法

Shell中获取字符串长度的七种方法 原文&#xff1a;http://blog.csdn.net/jerry_1126/article/details/51835119 求字符串操作在shell脚本中很常用&#xff0c;下面归纳、汇总了求字符串的几种可能方法: 【方法一】:利用${#str}来获取字符串的长度 【方法二】:利用awk的length方…

linux下用core和gdb查询出现段错误的地方

有些时候我们在一段C代码的时候&#xff0c;由于对一个非法内存进行了操作&#xff0c;在程序运行的过程中&#xff0c;出现了"段错误"。呵呵&#xff0c;这种问题我想很多人会经常遇到。遇到这种问题是非常无语的&#xff0c;只是提示了"段错误"&#xff…

什么是js的严格模式

设立严格模式的原因&#xff1a; - 消除Javascript语法的一些不合理、不严谨之处&#xff0c;减少一些怪异行为; - 消除代码运行的一些不安全之处&#xff0c;保证代码运行的安全&#xff1b; - 提高编译器效率&#xff0c;增加运行速度&#xff1b; - 为未来新版本的Javascrip…

代码解说Android Scroller、VelocityTracker

在编写自己定义滑动控件时经常会用到Android触摸机制和Scroller及VelocityTracker。Android Touch系统简单介绍&#xff08;二&#xff09;:实例具体解释onInterceptTouchEvent与onTouchEvent的调用过程对Android触摸机制须要用到的函数进行了具体的解释。本文主要介绍两个重要…

支付宝支付

1 申请商户平台 2 申请开放平台 3 申请APP支付 4 创建应用 (名称&#xff0c;logo) 5 生成RSA秘钥&#xff08;公钥&#xff0c;私钥&#xff09; 6 在应用中配置公钥 7 配置其他内容&#xff0c;包括iOS bundle ID。配置安卓包名&#xff0c;和签名。 获取appid&#xff0c;公…

不可错过的CMS学习笔记

引子 带着问题去学习一个东西&#xff0c;才会有目标感&#xff0c;我先把一直以来自己对CMS的一些疑惑罗列了下&#xff0c;希望这篇学习笔记能解决掉这些疑惑&#xff0c;希望也能对你有所帮助。 CMS出现的初衷、背景和目的&#xff1f; CMS的适用场景&#xff1f; CMS的tr…

相机工作原理

轻轻一按&#xff0c;你的相机就把光子转换为了比特。于是一张相片就保存到了你的 iPhone 里。 让我们假设一下你身处室外&#xff0c;环顾四周。三亿里之外&#xff0c;太阳无时无刻不在发射光子。它们需要花上 8 分钟之久才能到达我们舒适的星球。有一些光子撞击到你周围的物…

CentOS用户和用户组的操作

2019独角兽企业重金招聘Python工程师标准>>> CentOS用户和用户组的操作 長得太帥忚四種檌 关注 2018.05.12 16:40* 字数 312 阅读 115评论 0喜欢 0 用户组的操作 1.添加用户组&#xff1a; groupadd 组名2.修改组名 groupmod -n 新组名 原组名删除用户组groupdel 组…

Linux用户空间与内核地址空间

Linux 操作系统和驱动程序运行在内核空间&#xff0c;应用程序运行在用户空间&#xff0c;两者不能简单地使用指针传递数据&#xff0c;因为Linux使用的虚拟内存机制&#xff0c;用户空间的数据可能被换出&#xff0c;当内核空间使用用户空间指针时&#xff0c;对应的数据可能不…

浅谈微信smali注入

作者&#xff1a;郭少雷 搞android搞了几年也没搞出个啥牛逼app出来&#xff0c;眼看时下最火的app微信如此火热&#xff0c;实在想搞搞它&#xff0c;索性就想着给它加点东西进去。 以下内容纯属本人个人爱好&#xff0c;仅限个人学习android用途以及对android的深入了解。 首…