结构型模式 - 代理模式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 ...
随机推荐
- day12-Servlet02
Servlet02 6.GET和POST请求的分发处理 开发Servlet,通常编写doGet,doPost方法.来对表单的get和post请求进行分发处理 例子 在web文件夹下面创建一个html页 ...
- JS数据结构与算法-概述
JS数据结构与算法概述 数据结构: 计算机存储, 组织数据的方式, 就像锅碗瓢盆 算法: 一系列解决问题的清晰指令, 就像食谱 两者关系: 程序 = 数据结构 + 算法 邂逅数据结构与算法 什么是数据 ...
- webpack优化项目
在使用vue 构建项目的时候 ,会用到vue.js, vue-router.js, 等库,通常打包的话会将这些公用的代码打包的一个文件中,导致该文件过大影响加载的速度.那么可以考虑使用cdn 加速的方 ...
- golang 概念理解
https://www.youtube.com/watch?v=cN_DpYBzKso https://blog.golang.org/gos-declaration-syntax 1.golang ...
- WSL优化之SSH远程登录篇
Some of the most devastating things that happen to you will teach you the most. 有些最打击你的事情反而教会你的东西越多. ...
- 如何精简 Prometheus 的指标和存储占用
前言 随着 Prometheus 监控的组件.数量.指标越来越多,Prometheus 对计算性能的要求会越来越高,存储占用也会越来越多. 在这种情况下,要优化 Prometheus 性能, 优化存储 ...
- 支持 equals 相等的对象(可重复对象)作为 WeakHashMap 的 Key
原文地址 代码地址 问题 长链接场景下通常有一个类似 Map<String, Set<Long>> 的结构,用来查找一个逻辑组内的哪些用户,String 类型的 Entry.k ...
- 树莓派(香橙派)通过.NET IoT 操作SPI编写屏幕驱动 顺手做个四足机器人(一)
摘要 这片文章主要是记录自己的整活过程,涉及到的技术包括.NET IoT, .NET Web, .NET MAUI,框架采用的也是最新的.NET 7. 本人是用的树莓派Zero 2 W(ubuntu- ...
- Training: Stegano I
原题链接:http://www.wechall.net/challenge/training/stegano1/index.php 很明显,这是一道图像隐写题,因为他说的 我们右键图片,点击其他窗口打 ...
- 深入浅出学习透析Nginx服务器的基本原理和配置指南「Keepalive性能分析实战篇」
Linux系统:Centos 7 x64 Nginx版本:1.11.5 Nginx 是一款面向性能设计的 HTTP 服务器,能反向代理 HTTP,HTTPS 和邮件相关(SMTP,POP3,IMAP) ...