• 我也设计模式——11.Proxy


    这个模式用途很多,先看它的UML:

        abstract public class Subject
        
    {
            
    abstract public void Request();
        }


        
    public class RealSubject : Subject
        
    {
            
    public override void Request()
            
    {
                
    //Do Something
            }

        }


        
    public class Proxy : Subject
        
    {
            
    private RealSubject realSubject;

            
    public override void Request()
            
    {
                
    //关键是这句话
                realSubject.Request();
            }

        }

     Client端使用如下:
                Subject subject = new Proxy();
                subject.Request();

    Proxy有以下用途:
    1.远程代理     Remoting和WebService都是基于此技术,这里就不多说了。
    2.虚代理        单元测试中的Mock技术,以及加载大图片/处理大对象时的等待过程
        Mock技术:如果现在的RealSubject类的Request()方法还没写好,可以继承Subject基类生成Proxy,这是Proxy类的Request()方法这么写:

            public override void Request()
            
    {
                
    //从配置文件中读取是否出于测试状态
                bool isTest = GetConfiguration("isText");

                
    if (isTest)
                
    {
                    
    //写一些期望的假操作
                }

                
    else
                
    {
                    realSubject.Request();
                }

            }

        加载大图片:

        public interface Imager
        
    {
            Image getImage();
        }


        
    public class LargeImage : Imager
        
    {
            
    public Image getImage()
            
    {
                
    return new Bitmap(@"BigImage.jpg"); ;
            }

        }


        
    public class ProxyImage : Imager
        
    {
            
    private Timer tm;
            
    private bool isReady;
            
    private LargeImage largeImage;
            
            
    public ProxyImage()
            
    {
                isReady 
    = false;

                tm 
    = new Timer(
                    
    delegate
                    
    {
                        isReady 
    = true;
                        tm.Dispose();
                    }
    ,
                    
    this100000);
            }

            
            
    public Image getImage()
            
    {
                
    if (isReady)
                
    {                
                    
    return largeImage.getImage();
                }

                
    else
                
    {
                    
    return new Bitmap("SmallImage.gif");
                }

            }

        }

    在Client端调用方法:

            private ProxyImage imgProxy;

            
    private void Form1_Load(object sender, EventArgs e)
            
    {
                imgProxy 
    = new ProxyImage();
            }


            
    private void btnLoad_Click(object sender, EventArgs e)
            
    {
                
    //Pic为一个PictureBox控件
                Pic.Image = imgProxy.getImage();
            }

    注意这句话:            
            tm = new Timer(
                    delegate
                    {
                        isReady = true;
                        tm.Dispose();
                    },
                    this, 10000, 0);
    关键就是这句话,开始isReady为false,加载小图片。10秒钟后才将isReady设置为true,并使Timer失效,从而再次调用ProxyImage的getImage()方法,加载大图片。

    3.保护代理     控制对原始对象的访问,如增加/去除权限

    原有系统的方法GetDisCount(),只有Role=管理员时才可以调用。

        public class CompDiscount
        
    {
            
    private string role;

            
    public string Role
            
    {
                
    get return role; }
                
    set { role = value; }
            }


            
    public Double GetDiscount()
            
    {
                
    if (role == "admin")
                
    {
                    
    return 1000;
                }

                
    else
                
    {
                    
    throw new Exception();
                }

            }

        }

    现在要直接使用这个方法,而跳过权限控制,可以从中派生出一个子类ProxyCompDiscount:



        public class ProxyCompDiscount : CompDiscount
        
    {
            
    private CompDiscount c;

            
    public ProxyCompDiscount()
            
    {
                c 
    = new CompDiscount();
                c.Role 
    = "admin";
            }


            
    public new Double GetDiscount()
            
    {
                
    return c.GetDiscount();
            }

        }

    以上是去除多余的权限,相当于短路操作。反之,也可以使用同样的方法,增加权限。

    4.智能指引     在访问对象时执行一些附加的操作,如强制类型集

        public class Field 
        
    {
            
    private string fieldName;

            
    public Field(string fieldName)
            
    {
                
    this.fieldName = fieldName;
            }

        }


        
    public class FieldCollection : CollectionBase
        
    {
            
    public int Add(Field field)
            
    {
                
    return InnerList.Add(field);
            }


            
    public Field Add(string fieldName)
            
    {
                Field field 
    = new Field(fieldName);
                Add(field);

                
    return field;
            }


            
    public void Add(params string[] fields)
            
    {
                
    foreach (string field in fields)
                
    {
                    Add(field);
                }

            }


            
    public Field this[int index]
            
    {
                
    get 
                
    {
                    
    return (Field)InnerList[index];
                }

            }


            
    public void Remove(Field field)
            
    {
                InnerList.Remove(field);
            }

        }

    在Client端,Proxy模式不用知道被代理的对象;而Decorator模式需要知道被修饰的对象。这是二者的区别。

  • 相关阅读:
    60阶单群同构于A5的证明
    Riemann映射定理
    一个特殊情形的Mittag-Leffler分解
    一个重要的函数
    指数有限的子群存在一个右陪集代表元系,同时也是左陪集代表元系
    素数的平方阶群必为Abel群
    $mathscr{F}$类
    一个多项式问题
    Mittag-Leffler定理,Weierstrass因子分解定理和插值定理
    C -Concatenating Teams (字符串hash)
  • 原文地址:https://www.cnblogs.com/Jax/p/913461.html
Copyright © 2020-2023  润新知