• 结构型模式 - 代理模式Proxy


    学习而来,代码是自己敲的。也有些自己的理解在里边,有问题希望大家指出。

    代理模式的定义与特点

            代理模式的定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。  

    在不改变原有代码的基础上,增加自己的东西。分为静态代理动态代理

    动态代理的底层:全是反射。并且动态代理类是动态生成的,并不是我们提前写好。这个目前我技术有限,写不明白,还需要大家帮帮我。
    动态代理分为两大类,基于接口的动态代理,基于类的动态代理。 

     代理模式的主要优点:

    • 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
    • 代理对象可以扩展目标对象的功能;
    • 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加了程序的可扩展性

    代理模式的主要缺点是:

    • 代理模式会造成系统设计中类的数量增加
    • 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
    • 增加了系统的复杂度;

    那么如何解决以上提到的缺点呢?答案是可以使用动态代理方式

     1. 模式的结构

    代理模式的主要角色如下。

    1. 抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
    2. 真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
    3. 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

    其结构图如图 1 所示。

    图1

    代码

    0.通用代码

    1. namespace DesignPattern.ProxyPattern
    2. {
    3. ///
    4. /// 出租接口
    5. ///
    6. internal interface IRent
    7. {
    8. ///
    9. /// 出租房子
    10. ///
    11. void Renting();
    12. }
    13. ///
    14. /// 房东
    15. ///
    16. public class Landlord : IRent
    17. {
    18. public void Renting()
    19. {
    20. Console.WriteLine("我是房东,要出租房子。我已经把钥匙交给了中介。");
    21. }
    22. }
    23. }

    1.静态代理相关案例代码:

    1. using DesignPattern.ProxyPattern;
    2. using System;
    3. namespace DesignPattern
    4. {
    5. internal class Program
    6. {
    7. static void Main(string[] args)
    8. {
    9. StaticProxyHelper();
    10. }
    11. #region Pattern - Proxy
    12. static void ProxyHelper()
    13. {
    14. Console.WriteLine("静态代理演示:");
    15. Console.WriteLine();
    16. RentStaticProxy proxy = new RentStaticProxy(new Landlord());
    17. proxy.Renting();
    18. Console.ReadLine();
    19. }
    20. #endregion
    21. }
    22. }
    23. //======================================================================================
    24. using System;
    25. namespace DesignPattern.ProxyPattern
    26. {
    27. ///
    28. /// 出租的静态代理
    29. ///
    30. public class RentStaticProxy : IRent
    31. {
    32. private Landlord landlord;
    33. public RentStaticProxy(Landlord landlord)
    34. {
    35. this.landlord = landlord;
    36. }
    37. public void Renting()
    38. {
    39. GetRentInfo();
    40. landlord.Renting();
    41. SeeHouse();
    42. SetCntract();
    43. GetFare();
    44. }
    45. public void GetRentInfo()
    46. {
    47. Console.WriteLine("中介得到你需要租房。并开始搜寻已代理的房源信息");
    48. }
    49. public void SeeHouse()
    50. {
    51. Console.WriteLine("中介带你看这个房子");
    52. }
    53. public void SetCntract()
    54. {
    55. Console.WriteLine("签租赁合同");
    56. }
    57. public void GetFare()
    58. {
    59. Console.WriteLine("中介收中介费");
    60. }
    61. }
    62. }


     2.动态代理相关案例代码:

    1. using DesignPattern.ProxyPattern;
    2. using System;
    3. namespace DesignPattern
    4. {
    5. internal class Program
    6. {
    7. static void Main(string[] args)
    8. {
    9. DynamicProxyHelper();
    10. }
    11. #region Pattern - Proxy
    12. static void DynamicProxyHelper()
    13. {
    14. Console.WriteLine("动态代理演示:");
    15. Console.WriteLine();
    16. DynamicProxy dynamicProxy = new DynamicProxy(new Landlord());
    17. IRent _rent = DynamicProxy.As();
    18. _rent.Renting();
    19. Console.WriteLine(dynamicProxy.ToString());
    20. Console.ReadLine();
    21. }
    22. #endregion
    23. }
    24. }
    25. //======================================================================================
    26. using System;
    27. using System.Collections.Generic;
    28. using System.Dynamic;
    29. using System.Text;
    30. namespace DesignPattern.ProxyPattern
    31. {
    32. public class DynamicProxy<T> : DynamicObject where T : class, new()
    33. {
    34. private readonly T subject;
    35. private Dictionary<string, int> m_methodCallCount = new Dictionary<string, int>();
    36. public string Info
    37. {
    38. get
    39. {
    40. var sb = new StringBuilder();
    41. foreach (var item in m_methodCallCount)
    42. {
    43. sb.AppendLine($"{item.Key} called {item.Value} time(s)");
    44. }
    45. return sb.ToString();
    46. }
    47. }
    48. public DynamicProxy(T subject)
    49. {
    50. this.subject = subject;
    51. }
    52. public static I As<I>() where I : class
    53. {
    54. if (!typeof(I).IsInterface)
    55. throw new ArgumentException("I must be an interface type!");
    56. //Console.WriteLine(typeof(T));
    57. DynamicProxy inter = new DynamicProxy(new T());
    58. return inter.subject as I;
    59. }
    60. public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    61. {
    62. try
    63. {
    64. Console.WriteLine($"Invoking{subject.GetType().Name}.{binder.Name} with arguments [{string.Join(".", args)}]");
    65. if (m_methodCallCount.ContainsKey(binder.Name))
    66. m_methodCallCount[binder.Name]++;
    67. else
    68. m_methodCallCount.Add(binder.Name, 1);
    69. result = subject.GetType().GetMethod(binder.Name).Invoke(subject, args);
    70. return true;
    71. }
    72. catch (Exception e)
    73. {
    74. result = null;
    75. return false;
    76. }
    77. }
    78. }
    79. }

      这个动态代理,我是真的整不明白了,学艺不精,还望谅解,日后技术提升上来了接着完善。







    希望大家:点赞,留言,关注咯~    
    😘😘😘😘

    唠家常

    小黑的今日分享结束啦,小伙伴们你们get到了么,你们有没有更好的办法呢,可以评论区留言分享,也可以加小黑的QQ:841298494,大家一起进步。

    • 客官,看完get之后记得点赞哟!
    • 小伙伴你还想要别的知识?好的呀,分享给你们😄

    今日推荐

  • 相关阅读:
    SpringBoot学习(四)NoSQL、接口文档、远程调用、消息服务、Web安全、可观测性、AOT
    [Linux初阶]常见的指令
    Linux nohup命令
    RabbitMQ核心模式
    CENTOS上的网络安全工具(十三)搬到Docker上(1)?
    transformers AutoModelForMaskedLM简单使用
    并发中级(第一篇)
    上位机图像处理和嵌入式模块部署(qmacvisual三个特色)
    nodejs+vue校园跑腿系统elementui
    数据结构与算法中的图
  • 原文地址:https://blog.csdn.net/Wenhao_China/article/details/127446437