了解C#中的代理模式

时间:2016-11-15 09:02:54

标签: c# proxy-pattern

假设我试图通过像这样的其他类来访问类的方法

class SuperClass
    {
        public interface ISubject
        {
            void Print();
        }
        private class Subject : ISubject
        {
            public void Print()
            {
                Console.WriteLine("this is a print");
            }
        }
       public class Proxy {
            ISubject subject;
            public void CallOtherMethod() {
                subject = new Subject();
                subject.Print();
            }
        }
    }
    class Client: SuperClass
    {
        static void Main() {
            Proxy proxy = new Proxy();
            proxy.CallOtherMethod();
        }
    } 

这被称为代理类吗?或者它需要有一个接口作为参考,那么我们必须调用该方法?比如像这样

class SuperClass
    {
        public interface ISubject
        {
            void Print();
        }
        private class Subject : ISubject
        {
            public void Print()
            {
                Console.WriteLine("this is a print");
            }
        }
        public class Proxy : ISubject
        {
            ISubject subject;
            public void Print()
            {
                subject = new Subject();
                subject.Print();
            }
        }
    }
    class Client : SuperClass
    {
        static void Main()
        {
            ISubject proxy = new Proxy();
            proxy.Print();
        }
    }

1 个答案:

答案 0 :(得分:2)

通常,代理模式针对拦截。也就是说,捕获对某些类型的某些(或所有)方法的调用,并在实际调用之前/之后执行某些操作。为此,Proxy必须从目标类型继承

例如:

public class Subject
{
    public virtual void Print()
    {
        Console.WriteLine("this is a print");
    }
}

public class SubjectProxy : Subject
{
    public override void Print()
    {
        Console.Write("Before calling base.Print()");
        base.Print();
        Console.Write("After calling base.Print()");
    }
}

现在,当您的代码中的某个时刻您需要Subject时,您实际上可能会获得SubjectProxy并仍将其视为Subject

public Subject GetSubject()
{
    return new SubjectProxy();
}

Subject subject = GetSubject();
subject.Print(); // would use the proxied method

(这并不是说实现拦截的唯一方法是通过继承。我认为有代理风格使用组合/装饰的变化来实现这一点)