代理模式 (Proxy Pattern)-结构型模式第四篇

  1. 《设计模式》系列序——写给未来的自己
  2. 工厂方法模式(Factory Method)-创建型模式第一篇
  3. 抽象工厂模式(Abstract Factory Pattern)-创建型模式第二篇
  4. 单例模式(Singleton Pattern)-创建型模式第三篇
  5. 建造者模式(Builder Pattern)-创建型模式第四篇
  6. 原型模式(Prototype Pattern)-创建型模式第五篇
  7. 装饰者模式 (Decorator Pattern)-结构型模式第一篇
  8. 组合模式 (Composite Pattern)-结构型模式第二篇
  9. 适配器模式 (Adapter Pattern)-结构型模式第三篇
  10. 代理模式 (Proxy Pattern)-结构型模式第四篇

过去的大半年时间,日子过的忙忙碌碌!今天奉献一篇设计模式系列的新文章,挑选再三,始终觉得Proxy模式是很好的选择,Let’s Go!

定义:

Proxy模式,简言之,它像一个代理人,或者说像一个包装盒,它用来封装、控制背后真实的对象,自己可以独立提供被外界访问的能力,它与背后真实的对象派生于相同的接口,但代理人通常会将对真实对象的调用更加简单化,以便外界更加容易的使用。在客户端看来,自己似乎是直接在操作被代理的真实对象,但事实是,所有的操作都经过代理人的封装、控制、包装,而这些额外的操作,对于客户端来说,似乎是透明的。

应用:

Proxy模式,透明了对原始真实对象的调用,使我们有能力在调用真实对象的前后执行额外的动作,所以我们可以将一些与业务无关的软件基础功能添加在前后的额外动作中。比如Exception Handling, Logging, Caching等。

倘若再结合一些DI/IoC容器、编译器,有能力动态或静态地创建真实对象的代理,便无须手动去编写代理类,此时若配合一些编程语言的语法元数据(比如Java 中的@Attribute,C#中的[Attribute]),便可以在调用真实对象的方法前后执行额外的动作(通常可以称之为Interceptor 或Filter),这便初步实现了AOP编程。

UML:

Proxy UML
UML

实例:

using System;
using System.Diagnostics;

namespace ProxyPattern
{

    public interface ISubject
    {
        string GetName();
    }

    public class RealSubject : ISubject
    {
        public RealSubject(string name)
        {
            Name = name;
        }
        public string Name { get; }

        public string GetName()
        {
            return Name;
        }
    }

    public class Proxy : ISubject
    {
        private ISubject RealSubject = new RealSubject("Foobar");
        public string GetName()
        {
            // Before invoking real method, we can perform additional functionality.
            if (Valid())
            {
                var rt = RealSubject.GetName();
                // After invoking real method, we also can perform others, for example logging an access. 
                Debug.Write("The GetName has been invoked.");
                return rt;
            }
            throw new UnauthorizedAccessException("You don't have enough rights.");
        }

        /// <summary>
        /// For example, a validation method which use to validate something.
        /// </summary>
        /// <returns></returns>
        private bool Valid()
        {
            var now = DateTime.Now;
            if (now > new DateTime(2020, 11, 1) && now < new DateTime(2022, 1, 1))
            {
                return true;
            }
            return false;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //The proxy wrapped real subject, client never known the detail behind it.
            ISubject subject = new Proxy();
            Console.WriteLine($"The user name is {subject.GetName()}");
            Console.Read();
        }
    }
}

输出:

Proxy Example
Proxy Example

Leave a comment

Your email address will not be published. Required fields are marked *