用心理解设计模式——代理模式 (Proxy Pattern)

前置文章: 用心理解设计模式——设计模式的原则 

设计模式相关代码已统一放至 我的 Github

一、定义

  结构型模式之一。

  Provide a surrogate or placeholder for another object to control acess to ot.

(为其他对象提供一种代理,以控制对这个对象的访问)

二、结构解析

  代理模式的一般结构有三种角色:抽象主题、真实主题(被代理者)、代理者。

  抽象主题,负责定义和声明真实主题要被代理的业务方法接口。

  真实主题,继承抽象主题,实现自己真实的业务方法接口。

  代理者,也继承抽象主题,拥有与真实主题(被代理者)相同的要被代理的业务方法接口, 从外观上看代理者与被代理者似乎一样。代理者内部依赖真实主题,实现这些业务方法接口时,最终调用了真实主题(被代理者)的业务方法,但可以在预先或之后进行了一些额外的处理。

三、评价

  代理模式封装了客户访问或控制真实主题(被代理者)的过程,充当代理作用,解除了客户和真实主题之间的直接耦合。

  各自职责变得清晰,符合开闭原则, 非常易扩展。

  在真实主题不唯一, 但代理过程相同时,只需新增真实主题类即可(对扩展开放),而不用修改已有的代理类和已有的真实主题类(对修改关闭)。

  在真实主题唯一, 但代理过程不同时,只需新增满足需求的代理类(对扩展开放),而不用修改已有的代理类和已有的真实主题类(对修改关闭)。

  在真实主题唯一, 代理过程也不同时,可以同时扩展且不用修改已有的代理类和已有的真实主题类。

四、实现

namespace Proxy
{
    //抽象主题
    public abstract class Subject
    {
        //定义和声明真实主题要被代理的业务方法接口
        public abstract void DoSth();
    }

    //真实主题
    public class RealSubject : Subject
    {
        //实现业务方法接口,真实要做的事情。
        public override void DoSth(){}
    }

    //代理者
    public class Proxy : Subject
    {
        //内部依赖真实主题
        private Subject subject = new RealSubject();

        //代理者拥有与真实主题(被代理者)
        public override void DoSth()
        {
            //额外的预先操作
            this.Before();
            //最终调用真实主题的业务方法
            this.subject.DoSth();
            //额外的后续操作
            this.After();
        }

        private void Before() { }
        private void After() { }
    }

    public class Client
    {
        static public void Main()
        {
            Proxy proxy = new Proxy();
            proxy.DoSth();
        }
    }
}

五、真实主题和代理过程扩展

namespace Proxy.ExpandBoth
{
    public abstract class Subject
    {
        public abstract void DoSth();
    }

    //真实主题A
    public class RealSubjectA : Subject
    {
        public override void DoSth() { }
    }

    //真实主题B
    public class RealSubjectB : Subject
    {
        public override void DoSth() { }
    }

    //代理X
    public class ProxyX : Subject
    {
        //在构造代理者时确定代理哪个真实主题
        private Subject subject = null;
        public ProxyX(Subject subject)
        {
            this.subject = subject;
        }

        public override void DoSth()
        {
            this.BeforeX();
            this.subject.DoSth();
            this.AfterX();
        }

        private void BeforeX() { }
        private void AfterX() { }
    }

    //代理Y
    public class ProxyY : Subject
    {
        //在构造代理者时确定代理哪个真实主题
        private Subject subject = null;
        public ProxyY(Subject subject)
        {
            this.subject = subject;
        }

        public override void DoSth()
        {
            this.BeforeB();
            this.subject.DoSth();
            this.AfterB();
        }

        private void BeforeB() { }
        private void AfterB() { }
    }

    public class Client
    {
        static public void Main()
        {
            RealSubjectA realSubjectA = new RealSubjectA();
            RealSubjectB realSubjectB = new RealSubjectB();

            //X代理真实主题A
            ProxyX proxyXA = new ProxyX(realSubjectA);
            proxyXA.DoSth();
            //X代理真实主题B
            ProxyX proxyXB = new ProxyX(realSubjectB);
            proxyXB.DoSth();
            //Y代理真实主题A
            ProxyY proxyYA = new ProxyY(realSubjectA);
            proxyYA.DoSth();
            //Y代理真实主题B
            ProxyY proxyYB = new ProxyY(realSubjectB);
            proxyYB.DoSth();
        }
    }
}

六、动态代理

  TODO

猜你喜欢

转载自blog.csdn.net/NRatel/article/details/84255740