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

代理模式的定义与特点
代理模式的定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
在不改变原有代码的基础上,增加自己的东西。分为静态代理和动态代理。
动态代理的底层:全是反射。并且动态代理类是动态生成的,并不是我们提前写好。这个目前我技术有限,写不明白,还需要大家帮帮我。
动态代理分为两大类,基于接口的动态代理,基于类的动态代理。

代理模式的主要优点:
- 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
- 代理对象可以扩展目标对象的功能;
- 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加了程序的可扩展性
代理模式的主要缺点是:
- 代理模式会造成系统设计中类的数量增加
- 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
- 增加了系统的复杂度;
那么如何解决以上提到的缺点呢?答案是可以使用动态代理方式
1. 模式的结构
代理模式的主要角色如下。
- 抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
- 真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
- 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。
其结构图如图 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之后记得点赞哟!
- 小伙伴你还想要别的知识?好的呀,分享给你们
今日推荐
结构型模式 - 代理模式Proxy的更多相关文章
- python设计模式---结构型之代理模式
主要想着nginx:) from abc import ABCMeta, abstractmethod # 结构型设计模式---代理模式 class Actor: def __init__(self) ...
- 【设计模式】结构型01代理模式(Proxy Pattern)
代理模式(Proxy Pattern) 定义:顾名思义,增加中间层,为其他对象提供一种代理以控制对这个对象的访问.核心在于代理二字. 1.和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理 ...
- JAVA设计模式 5【结构型】代理模式的理解与使用
今天要开始我们结构型 设计模式的学习,设计模式源于生活,还是希望能通过生活中的一些小栗子去理解学习它,而不是为了学习而学习这些东西. 结构型设计模式 结构型设计模式又分为 类 结构型 对象 结构型 前 ...
- 结构型:代理模式 Vs 适配器模式 Vs 门面模式(外观模式)
先上UML图 代理模式: 适配器模式: 门面模式(外观模式): 打了例子……呃……举个比方 代理模式: 水浒街,西门庆看上潘金莲,想和她嘿咻嘿咻,但是自己有不能去找潘金莲去说,于是他找到了金牌代理人王 ...
- 《精通Python设计模式》学习结构型之代理模式
这种模式,总会让人想到SRPING中的AOP, 不同语言有不同的实现方式吧. class SensitiveInfo: def __init__(self): self.users = ['nick' ...
- 【结构型】Flyweight模式
享元模式的主要目的.意图是为对象的大量使用提供一种共享机制.该模式的思想重在复用.共享复用.像文字.列表中的格子等这类多数都是需要考虑复用技术,否则必将大量耗费内存空间而使资源以及性能等大量耗费.该模 ...
- java设计模式--结构型模式--代理模式
代理模式 概述 为其他对象提供一种代理以控制对这个对象的访问. 适用性 1.远程代理(RemoteProxy)为一个对象在不同的地址空间提供局部代表. 2.虚代理(VirtualProxy)根据需要创 ...
- Proxy模式 代理模式
Android的 LocalWindowManager 和 WindowManagerImgl 都实现了WindowManager接口.LocalWindowManager 中保存一个WindowMa ...
- 【设计模式】结构型04桥接模式(Bridge Pattern)
学习地址:http://www.runoob.com/design-pattern/bridge-pattern.html 桥接模式(Bridge Pattern) 桥接模式(Bridge patte ...
随机推荐
- Qt--无边框窗口完美(FrameLess)实现,包含缩放和移动功能重写。
前言 Qt原本的窗口虽然可以通过QSS样式进行美化,但是只是对客户区有用,对于客户区是无效的.所以想做出一个比较好看的程序,还得自己重写实现无边框窗口. Qt实现无边框其实一句代码就可以,但是窗口自带 ...
- ES的java端API操作
首先简单介绍下写这篇博文的背景,最近负责的一个聚合型的新项目要大量使用ES的检索功能,之前对es的了解还只是纯理论最多加个基于postman的索引创建操作,所以这次我得了解在java端如何编码实现:网 ...
- 基于python的数学建模---非线性规划
凸函数的非线性规划 minimize 求解的是局部最优解 简单的函数,无所谓 复杂的函数 初始值的设定很重要 scipy.optimize.minimize(fun,x0,args=(),method ...
- 我的Vue之旅 11 Vuex 实现购物车
Vue CartView.vue script 数组的filter函数需要return显式返回布尔值,该方法得到一个新数组. 使用Vuex store的modules方式,注意读取状态的方式 this ...
- 基于echarts的带流动光效的折线图-lowline-for-echarts使用记录
起源 在技术群看到有人问这个react插件,带着好奇心看了一下. 标题:基于echarts的带流动光效的折线图 - 掘金 网址:https://juejin.cn/post/7090566240233 ...
- typora使用CSDN图床
前言 软件下载地址 typora 是一款好用的 markdown 文档编辑器. 我之前研究过CSDN上传图片的接口,前几天发现了Typora 这个好用的软件,可以自定义图床,因为我很多文章图片资源用的 ...
- 关于CSDN获取博客内容接口的x-ca-signature签名算法研究
前言 源码下载 不知道怎么就不通过了,这篇文章放出去几个月了,然后突然告诉我不行了,所以我打算换个平台(至少不能在一棵树吊死),垃圾审核 我最初想直接获取html博客,然后保存在本地,最后发布到别的博 ...
- 求10以内所有偶数和-Java
public class Demo{ //求10以内所有偶数和 public static void main (String[] args){ int sum = 0; for(int i = 0; ...
- 100IT 名企 java 面试必考面试题
一.Java基础(2/133) 二.Java代码报错(52/133) 三.算法与编程(55/133) 四.html&JavaScript&ajax部分 五.Java Web部分 六.数 ...
- 【Spark】Day04-Spark Streaming:与离线批量比较、架构特点、入门案例、创建(队列、数据源)、转换(有状态、无状态)、输出方式、进阶(累加、转换为DF、缓存持久化)、实战(窗口统计)
一.概述 1.离线和实时计算 离线:数据量大,数据不会变化,MapReduce 实时:数据量小,计算过程要短 2.批量和流式处理 批量:冷数据,数据量大,速度慢 流:在线.实时产生的数据(快速持续到达 ...