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

代理模式的定义与特点

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

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

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

代理模式的主要优点:

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

代理模式的主要缺点是:

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

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

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之后记得点赞哟!
  • 小伙伴你还想要别的知识?好的呀,分享给你们

今日推荐

结构型模式 - 代理模式Proxy的更多相关文章

  1. python设计模式---结构型之代理模式

    主要想着nginx:) from abc import ABCMeta, abstractmethod # 结构型设计模式---代理模式 class Actor: def __init__(self) ...

  2. 【设计模式】结构型01代理模式(Proxy Pattern)

    代理模式(Proxy Pattern) 定义:顾名思义,增加中间层,为其他对象提供一种代理以控制对这个对象的访问.核心在于代理二字. 1.和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理 ...

  3. JAVA设计模式 5【结构型】代理模式的理解与使用

    今天要开始我们结构型 设计模式的学习,设计模式源于生活,还是希望能通过生活中的一些小栗子去理解学习它,而不是为了学习而学习这些东西. 结构型设计模式 结构型设计模式又分为 类 结构型 对象 结构型 前 ...

  4. 结构型:代理模式 Vs 适配器模式 Vs 门面模式(外观模式)

    先上UML图 代理模式: 适配器模式: 门面模式(外观模式): 打了例子……呃……举个比方 代理模式: 水浒街,西门庆看上潘金莲,想和她嘿咻嘿咻,但是自己有不能去找潘金莲去说,于是他找到了金牌代理人王 ...

  5. 《精通Python设计模式》学习结构型之代理模式

    这种模式,总会让人想到SRPING中的AOP, 不同语言有不同的实现方式吧. class SensitiveInfo: def __init__(self): self.users = ['nick' ...

  6. 【结构型】Flyweight模式

    享元模式的主要目的.意图是为对象的大量使用提供一种共享机制.该模式的思想重在复用.共享复用.像文字.列表中的格子等这类多数都是需要考虑复用技术,否则必将大量耗费内存空间而使资源以及性能等大量耗费.该模 ...

  7. java设计模式--结构型模式--代理模式

    代理模式 概述 为其他对象提供一种代理以控制对这个对象的访问. 适用性 1.远程代理(RemoteProxy)为一个对象在不同的地址空间提供局部代表. 2.虚代理(VirtualProxy)根据需要创 ...

  8. Proxy模式 代理模式

    Android的 LocalWindowManager 和 WindowManagerImgl 都实现了WindowManager接口.LocalWindowManager 中保存一个WindowMa ...

  9. 【设计模式】结构型04桥接模式(Bridge Pattern)

    学习地址:http://www.runoob.com/design-pattern/bridge-pattern.html 桥接模式(Bridge Pattern) 桥接模式(Bridge patte ...

随机推荐

  1. 驱动开发:内核层InlineHook挂钩函数

    在上一章<驱动开发:内核LDE64引擎计算汇编长度>中,LyShark教大家如何通过LDE64引擎实现计算反汇编指令长度,本章将在此基础之上实现内联函数挂钩,内核中的InlineHook函 ...

  2. JS 学习笔记(二)Ajax的简单使用

    使用Ajax访问本地TXT文件 ajax.js // 创建请求对象 var ajax = new XMLHttpRequest(); // 建立连接 ajax.open('get', 'test.tx ...

  3. Redis可视化管理工具-RedisDesktopManager

    Windows客户端,访问Redis数据库并执行一些基本操作. 链接:https://pan.baidu.com/s/1OuGqIfbpGwglC-642rECbQ 提取码:m6uo

  4. ES的java端API操作

    首先简单介绍下写这篇博文的背景,最近负责的一个聚合型的新项目要大量使用ES的检索功能,之前对es的了解还只是纯理论最多加个基于postman的索引创建操作,所以这次我得了解在java端如何编码实现:网 ...

  5. beego-orm-sqlite

    dao.go ``` package daoimport ( "fmt" "github.com/astaxie/beego/orm" "html&q ...

  6. Kubernetes_手把手打镜像并运行到k8s容器上(亲测可用)

    一.前言 本文使用两个机器 192.168.100.150 是master节点,192.168.100.151 是node1 节点,如下: 演示三个示例,第一个示例wordpress博客系统是指将别人 ...

  7. i春秋xss平台

    点开是个普普通通的登录窗口,没有注册,只有登录,抓住包也没获取什么有用的信息,看了看dalao的wp才知道怎么做,首先抓包然后修改参数的定义来让其报错,pass原本的应该为整数,pass[]=就可以让 ...

  8. easyui textbox setvalue 和 settext前后之别

    今天在这里转了好久,浪费了不少时间.话不多说直接上干货: 1.text与value设置不同的值一定要先赋值 value后赋值text, 否则全为value值 2.若只setValue,则getValu ...

  9. MathNet用到的一些功能

    1.计算一元线性函数 Tuple<double, double> myLineTuple = MathNet.Numerics.Fit.Line(myXArray, myYArray); ...

  10. 【Java面试指北】Exception Error Throwable 你分得清么?

    读本篇文章之前,如果让你叙述一下 Exception Error Throwable 的区别,你能回答出来么? 你的反应是不是像下面一样呢? 你在写代码时会经常 try catch(Exception ...