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

代理模式的定义与特点

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

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

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

代理模式的主要优点:

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

代理模式的主要缺点是:

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

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

1. 模式的结构

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

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

其结构图如图 1 所示。

图1

代码

0.通用代码

namespace DesignPattern.ProxyPattern
{
/// <summary>
/// 出租接口
/// </summary>
internal interface IRent
{
/// <summary>
/// 出租房子
/// </summary>
void Renting();
} /// <summary>
/// 房东
/// </summary>
public class Landlord : IRent
{
public void Renting()
{
Console.WriteLine("我是房东,要出租房子。我已经把钥匙交给了中介。");
}
}
}

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

using DesignPattern.ProxyPattern;
using System; namespace DesignPattern
{
internal class Program
{
static void Main(string[] args)
{
StaticProxyHelper();
} #region Pattern - Proxy
static void ProxyHelper()
{
Console.WriteLine("静态代理演示:");
Console.WriteLine();
RentStaticProxy proxy = new RentStaticProxy(new Landlord());
proxy.Renting(); Console.ReadLine();
}
#endregion
}
} //====================================================================================== using System; namespace DesignPattern.ProxyPattern
{
/// <summary>
/// 出租的静态代理
/// </summary>
public class RentStaticProxy : IRent
{
private Landlord landlord; public RentStaticProxy(Landlord landlord)
{
this.landlord = landlord;
} public void Renting()
{
GetRentInfo();
landlord.Renting();
SeeHouse();
SetCntract();
GetFare();
} public void GetRentInfo()
{
Console.WriteLine("中介得到你需要租房。并开始搜寻已代理的房源信息");
}
public void SeeHouse()
{
Console.WriteLine("中介带你看这个房子");
} public void SetCntract()
{
Console.WriteLine("签租赁合同");
}
public void GetFare()
{
Console.WriteLine("中介收中介费");
}
}
}


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

using DesignPattern.ProxyPattern;
using System; namespace DesignPattern
{
internal class Program
{
static void Main(string[] args)
{
DynamicProxyHelper();
} #region Pattern - Proxy
static void DynamicProxyHelper()
{
Console.WriteLine("动态代理演示:");
Console.WriteLine(); DynamicProxy<Landlord> dynamicProxy = new DynamicProxy<Landlord>(new Landlord());
IRent _rent = DynamicProxy<Landlord>.As<IRent>();
_rent.Renting();
Console.WriteLine(dynamicProxy.ToString()); Console.ReadLine();
}
#endregion
}
} //====================================================================================== using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Text; namespace DesignPattern.ProxyPattern
{
public class DynamicProxy<T> : DynamicObject where T : class, new()
{
private readonly T subject;
private Dictionary<string, int> m_methodCallCount = new Dictionary<string, int>(); public string Info
{
get
{
var sb = new StringBuilder();
foreach (var item in m_methodCallCount)
{
sb.AppendLine($"{item.Key} called {item.Value} time(s)");
}
return sb.ToString();
}
} public DynamicProxy(T subject)
{
this.subject = subject;
} public static I As<I>() where I : class
{
if (!typeof(I).IsInterface)
throw new ArgumentException("I must be an interface type!"); //Console.WriteLine(typeof(T));
DynamicProxy<T> inter = new DynamicProxy<T>(new T());
return inter.subject as I;
} public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
try
{
Console.WriteLine($"Invoking{subject.GetType().Name}.{binder.Name} with arguments [{string.Join(".", args)}]"); if (m_methodCallCount.ContainsKey(binder.Name))
m_methodCallCount[binder.Name]++;
else
m_methodCallCount.Add(binder.Name, 1); result = subject.GetType().GetMethod(binder.Name).Invoke(subject, args);
return true;
}
catch (Exception e)
{
result = null;
return false;
}
}
}
}

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







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

唠家常

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

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

今日推荐

最新文章

  1. CSS3常用属性(边框、背景、文本效果、2D转换、3D转换、过渡、有过渡效果大图轮播、动画)
  2. Common Issues Which Cause Roles to Recycle
  3. 批处理命令——for
  4. BZOJ 1433 二分图上的博弈
  5. NoSuchMethodError: antlr.collections.AST.getLine()I
  6. 超实用的JavaScript代码段 Item8 -- js对象的(深)拷贝
  7. struts2之请求参数接收
  8. C#经典系列-跨语言
  9. 利用linux信号机制调试段错误(Segment fault)
  10. php秒杀
  11. 修炼dp( 2 )
  12. 相机标定:kalibr标定工具箱使用总结
  13. 企业账号打包如何通过HTML页面打开
  14. MacOS 下安装mysqlclient 的问题及解决办法
  15. alpha-咸鱼冲刺day8-紫仪
  16. 解决:在微信中访问app下载链接提示“已停止访问该网页”
  17. yosay
  18. 自学Python3.4-函数分类(匿名函数)
  19. [转]Angular CLI 安装和使用
  20. Linux基础命令---添加用户useradd

热门文章

  1. 并发编程之 ThreadLocal
  2. 聪明的暴力枚举求abcde/fghij=n
  3. 成熟企业级开源监控解决方案Zabbix6.2关键功能实战-上
  4. 「浙江理工大学ACM入队200题系列」问题 A: 零基础学C/C++34—— 3个数比较大小(冒泡排序与选择排序算法)
  5. Optional对象
  6. 【云原生 · Kubernetes】Kubernetes Node的隔离与恢复
  7. Day18.2:对象创建的内存分析图解
  8. 模拟Promise的功能
  9. Excel2010工作簿被锁定,无法复制或者新增加sheet表格。
  10. angr_ctf——从0学习angr(一):angr简介与核心概念