一、说买电脑的那些事
      我
之前一直用的是台式机,可总感觉不方便,特别是携带,就拿租房子后搬家来说吧,费了不少劲。种种原因有了想换笔记本的想法。 5.1假期和一个好朋友特到电脑城去逛了一圈,一进电脑城便见:“HP笔记本XX总代理、IBM笔记本专卖、XX电脑YY总代理......”。

      看了很多家销售店,给我印象最深的就是到处都是XX牌电脑专卖和代理商,就在同一层楼里我就见着同一牌子有6家代理销售商铺。呵呵,看来我们买电脑就直接找销售代理商就可以,没必要在找生产厂商了,厂商生产出电脑后就是要把产品推向市场销售出去,而代理商在此过程中就代替生产商销售产品。这让我想起了面向对象的设计模式--代理(Proxy)模式

二、谈代理(Proxy)模式
  1、代理模式的意图:
     为其他对象提供一种代理以控制对这个对象的访问。
     就以电脑销售代理商来说,他就负责提供一种代理,以控制对电脑制造商销售电脑的方法。

  2、代理模式UML图(下图选自[url]http://www.dofactory.com/[/url]
       谈代理(Proxy)模式,从买电脑的那些事说起_代理
  3、代理模式的动机:
     对一个对象进行访问控制的一个原因是为了只有在我们确实需要这个对象时才对它进行创建和初始化。问题的解决方案
    是使用另一个对象,以电脑销售例子来分析,既电脑销售代理商(ComputerProxy),来替代电脑制造商   (ComputerMaker)。电脑销售代理商可以代替电脑制造商销售电脑,并且在需要的时候(客户在买电脑的时候)负责实
    例化ComputerMaker对象。见下电脑销售代理图:
                   谈代理(Proxy)模式,从买电脑的那些事说起_代理_02
1谈代理(Proxy)模式,从买电脑的那些事说起_代理_03//电脑代理商销售电脑的方法,当客户在买电脑的时候就调用此方
2谈代理(Proxy)模式,从买电脑的那些事说起_代理_03//法销售电脑,此时就需要去实例化ComputerMaker对象。
3谈代理(Proxy)模式,从买电脑的那些事说起_代理_03public void SaleComputer()
4谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_06{  
5谈代理(Proxy)模式,从买电脑的那些事说起_模式_09   if(cm==null)      
6谈代理(Proxy)模式,从买电脑的那些事说起_模式_10   {     
7谈代理(Proxy)模式,从买电脑的那些事说起_模式_09      cm = new ComputerMaker();
8谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14   }

9谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_15}
  4、代理模式的适用性:
     在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用代理(Proxy)模式。--选自《设计模式--可复用面
     向对象软件基础》
     比如我们现实生活中的房地产代理、职业介绍所、本文前所提到的电脑销售代理商等。
     西游记里美猴子王孙悟空代高×××出嫁猪八戒,并制服八戒的故事。

  5、模式的参与者(对比上面电脑销售代理图):
     抽象主题角色(Subject)
     --定义真实主题角色(RealSubject)和主题代理角色(Proxy)的共用接口,这样就在任何使用真实主题角色的地方都可
        以使用主题代理角色。
     就如买电脑,我们可以直接找电脑制造商买电脑,也可以找电脑销售代理商买电脑。

     真实主题角色(RealSubject)
     --定义主题代理角色(Proxy)所代表的实体。

     主题代理角色(Proxy)
     --持有一个真实主题角色的引用,使得代理角色可以直接访问真实主题角色。提供一个与抽象主题角色的接口相同的接
     口方法,这样代理角色就可以用来替代真实主题角色。
     其他的功能依赖于代理的类型,这里就不作过多介绍,详细可查看《设计模式--可复用面向对象软件基础》或其他相
     关资料。
     在电脑的销售体系中,电脑销售代理商完全可以替代电脑制造商销售电脑(如果行不通就不会有那么多的代理商了)。

  6、协作关系:
      --代理根据其种类,在适当的时候向真实主题角色(RealSubject)转发请求。
      买电脑的过程中,我们找的是电脑销售代理商,调用其销售电脑的方法(SaleComputer方法),让他销售一台或多台
      电脑给我们,而他
在这个时候就把请求转发给了电脑制造商(真实主题角色),调用其销售电脑的方法(SaleComputer方
      法)。然而在整个代理中,主题代理角
色持有一个真实主题角色的引用,既:
谈代理(Proxy)模式,从买电脑的那些事说起_代理_03ComputerMaker cm = null;
    主题代理角色在向真实主题角色转发请求实际也就是通过他所持有的真实主题角色的引用去调用真实主题角色的方法,如
    下:
1谈代理(Proxy)模式,从买电脑的那些事说起_代理_03if(cm==null
2谈代理(Proxy)模式,从买电脑的那些事说起_代理_18{    
3谈代理(Proxy)模式,从买电脑的那些事说起_模式_09  cm = new ComputerMaker();
4谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_15}
  
5谈代理(Proxy)模式,从买电脑的那些事说起_代理_03cm.SaleComputer();
  7、模式效果
      --代理模式在访问对象时引入了一定程度的间接性。
      在我们买电脑的过程中,我们找电脑销售代理商买电脑,调用其销售电脑的方法,而实际是间接的调用了电脑制造商的
      销售电脑方法。

三、电脑销售代理程序
谈代理(Proxy)模式,从买电脑的那些事说起_模式_24
 1谈代理(Proxy)模式,从买电脑的那些事说起_代理_03namespace DesignPattern.Proxy.Computer
 2谈代理(Proxy)模式,从买电脑的那些事说起_模式_26{
 3谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_29    /// <summary>
 4谈代理(Proxy)模式,从买电脑的那些事说起_模式_09    /// 抽象主题角色--声明了真实主题与代理主题的共同接口(共有的特性)。
 5谈代理(Proxy)模式,从买电脑的那些事说起_模式_09    /// 在任何使用真实主题的地方都可以使用代理主题
 6谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14    /// </summary>

 7谈代理(Proxy)模式,从买电脑的那些事说起_模式_09    public abstract class Computer
 8谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_35    {
 9谈代理(Proxy)模式,从买电脑的那些事说起_代理_38        /// <summary>
10谈代理(Proxy)模式,从买电脑的那些事说起_模式_09        /// 抽象的主题行为--销售电脑(不管代理商还是制造商,他们的目的就是销售出去产品)
11谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14        /// </summary>

12谈代理(Proxy)模式,从买电脑的那些事说起_模式_09        public abstract void SaleComputer();
13谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14    }

14谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_15}

谈代理(Proxy)模式,从买电脑的那些事说起_休闲_45
 1谈代理(Proxy)模式,从买电脑的那些事说起_代理_03namespace DesignPattern.Proxy.Computer
 2谈代理(Proxy)模式,从买电脑的那些事说起_电脑_47{
 3谈代理(Proxy)模式,从买电脑的那些事说起_休闲_50    /// <summary>
 4谈代理(Proxy)模式,从买电脑的那些事说起_模式_09    /// 真实的主题角色--定义了代理角色所代表的真实对象(电脑制造商)。
 5谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14    /// </summary>

 6谈代理(Proxy)模式,从买电脑的那些事说起_模式_09    public class ComputerMaker:Computer
 7谈代理(Proxy)模式,从买电脑的那些事说起_代理_55    {
 8谈代理(Proxy)模式,从买电脑的那些事说起_模式_58        /// <summary>
 9谈代理(Proxy)模式,从买电脑的那些事说起_模式_09        /// 制造商可以直接销售电脑
10谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14        /// </summary>

11谈代理(Proxy)模式,从买电脑的那些事说起_模式_09        public override void SaleComputer()
12谈代理(Proxy)模式,从买电脑的那些事说起_模式_63        {
13谈代理(Proxy)模式,从买电脑的那些事说起_模式_09            Console.WriteLine("制造商售出一台电脑!");
14谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14        }

15谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14    }

16谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_15}
 
 1谈代理(Proxy)模式,从买电脑的那些事说起_代理_03namespace DesignPattern.Proxy.Computer
 2谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_71{
 3谈代理(Proxy)模式,从买电脑的那些事说起_代理_74    /// <summary>
 4谈代理(Proxy)模式,从买电脑的那些事说起_模式_09    /// 代理主题角色--含有对真实主题角色的引用(操作真实主体对象),代理角色通常在将客户端调用传递给真实主题
 5谈代理(Proxy)模式,从买电脑的那些事说起_模式_09    /// 对象的之前或者之后都会执行某些操作(方法),而不是只单纯的返回真实的对象。
 6谈代理(Proxy)模式,从买电脑的那些事说起_模式_09    /// 
 7谈代理(Proxy)模式,从买电脑的那些事说起_模式_09    /// 电脑销售代理商--通过优惠打折扣或送礼品等多种方式吸引客户。
 8谈代理(Proxy)模式,从买电脑的那些事说起_模式_09    /// 代理角色所代理的真实对象--电脑制造商
 9谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14    /// </summary>

10谈代理(Proxy)模式,从买电脑的那些事说起_模式_09    public class ComputerProxy:Computer
11谈代理(Proxy)模式,从买电脑的那些事说起_休闲_83    {
12谈代理(Proxy)模式,从买电脑的那些事说起_模式_09        //持有真实主题角色的引用
13谈代理(Proxy)模式,从买电脑的那些事说起_模式_09        private ComputerMaker cm = null;
14谈代理(Proxy)模式,从买电脑的那些事说起_模式_09
15谈代理(Proxy)模式,从买电脑的那些事说起_模式_09        public override void SaleComputer()
16谈代理(Proxy)模式,从买电脑的那些事说起_模式_90        {
17谈代理(Proxy)模式,从买电脑的那些事说起_模式_09            this.Discount();
18谈代理(Proxy)模式,从买电脑的那些事说起_模式_09            this.GiveMouse();
19谈代理(Proxy)模式,从买电脑的那些事说起_模式_09            if (cm == null)
20谈代理(Proxy)模式,从买电脑的那些事说起_休闲_96            {
21谈代理(Proxy)模式,从买电脑的那些事说起_模式_09                cm = new  ComputerMaker();
22谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14            }

23谈代理(Proxy)模式,从买电脑的那些事说起_模式_09            //通过真实主题角色引用调用销售卖电脑方法(真实主题角色的行为)
24谈代理(Proxy)模式,从买电脑的那些事说起_模式_09            cm.SaleComputer();
25谈代理(Proxy)模式,从买电脑的那些事说起_模式_09
26谈代理(Proxy)模式,从买电脑的那些事说起_模式_09            //此时代理商就完成了电脑的销售,还给了客户优惠和礼品。
27谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14        }

28谈代理(Proxy)模式,从买电脑的那些事说起_模式_09
29谈代理(Proxy)模式,从买电脑的那些事说起_模式_09        public void Discount()
30谈代理(Proxy)模式,从买电脑的那些事说起_模式_108        {
31谈代理(Proxy)模式,从买电脑的那些事说起_模式_09            Console.WriteLine("我给你8折优惠!");
32谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14        }

33谈代理(Proxy)模式,从买电脑的那些事说起_模式_09
34谈代理(Proxy)模式,从买电脑的那些事说起_模式_09        public void GiveMouse()
35谈代理(Proxy)模式,从买电脑的那些事说起_休闲_115        {
36谈代理(Proxy)模式,从买电脑的那些事说起_模式_09            Console.WriteLine("我还送你一个鼠标!");
37谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14        }

38谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14    }

39谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_15}


谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_122
 1谈代理(Proxy)模式,从买电脑的那些事说起_代理_03namespace DesignPattern.Proxy
 2谈代理(Proxy)模式,从买电脑的那些事说起_代理_124{
 3谈代理(Proxy)模式,从买电脑的那些事说起_模式_09    class Program
 4谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_128    {
 5谈代理(Proxy)模式,从买电脑的那些事说起_模式_09        static void Main(string[] args)
 6谈代理(Proxy)模式,从买电脑的那些事说起_电脑_132        {
 7谈代理(Proxy)模式,从买电脑的那些事说起_模式_136            #region Computer
 8谈代理(Proxy)模式,从买电脑的那些事说起_模式_09            Console.WriteLine("--制造商销售电脑--");
 9谈代理(Proxy)模式,从买电脑的那些事说起_模式_09            Computer.Computer sc = new ComputerMaker();
10谈代理(Proxy)模式,从买电脑的那些事说起_模式_09            sc.SaleComputer();
11谈代理(Proxy)模式,从买电脑的那些事说起_模式_09
12谈代理(Proxy)模式,从买电脑的那些事说起_模式_09            Console.WriteLine();
13谈代理(Proxy)模式,从买电脑的那些事说起_模式_09            Console.WriteLine("--代理商销售电脑--");
14谈代理(Proxy)模式,从买电脑的那些事说起_模式_09            sc = new ComputerProxy();
15谈代理(Proxy)模式,从买电脑的那些事说起_模式_09            sc.SaleComputer();
16谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14            #endregion

17谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14        }

18谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_14    }

19谈代理(Proxy)模式,从买电脑的那些事说起_Proxy_15}
 
四、代理(Proxy)模式大观园:
     当我们去操作或控制一个对象时,如果该对象处于某种原因不能被调用方直接控制或操作,Proxy模式就该出场了。Proxy模式中的“代理”代表了被代理对象的权利和义务。而这种义务不同于法律文件规定的义务,而是设计者通过一定的设计方式,例如继承或者聚合的方式来获得的。
     虽然我们的设计模式开山老祖GOF在其经典著作《设计模式》一书中阐明,Proxy模式的意图是“为其他对象提供一种代理以控制对这个对象的访问。”描述一目了然,但实际的应用方式,却需要在项目中去体现。
     Proxy模式的应用非常广泛,还包括远程代理,智能代理......等。虽然实现方式不一样,但其中的原理却是相同的,要理解Proxy模式,只要明白“代理”二字的含义就可以一目了然了。----选自《软件设计精要与模式》

五、其他相关模式
     Adapter:适配器(Adapter)模式为它所适配的对象提供一个 不同的接口。相反,代理模式提供了与它的实体相同的接口。然而,用于访问保护的代理可能会拒绝执行实体会执行的操作,因此,它的接口实际上可能只是实体接口的一个子集。--选自《设计模式--可复用面向对象软件基础》

六、参考文献
   《设计模式--可复用面向对象软件基础》
   《软件设计精要与模式》
    [url]http://www.dofactory.com/[/url]