前言
代理模式主要是用来对目标对象访问权限的控制,比如游戏商城里购买道具时,通过代理类去判断玩家是否可以执行购买操作,然后比较与装饰器的区别。
1.静态代理模式详解
代理模式不管目标对象原方法做了什么,它只关心用户是否有权限访问目标对象方法。代理类相当于一个安全权限层,如果在目标对象添加安全或权限判断的逻辑,代码就比较耦合,所以需要把权限层和功能层分离起来。接下来用游戏商城里购买道具来讲解静态代理类的实现,具体代码如下:
public interface IGamePayment
{
void RequestTransaction(int num);
void StopTransaction();
void TransactionResult(bool result);
}
public class GameShop : IGamePayment
{
public void BuyProp(string name)//购买道具
{
Console.WriteLine("购买道具");
}
public void ExchangeProp(string name)//激活码兑换道具
{
Console.WriteLine("兑换道具");
}
public void RequestTransaction(int num)
{
//TODO 发起购买钻石请求
}
public void StopTransaction()
{
//TODO 终止购买钻石请求
}
public void TransactionResult(bool result)
{
//TODO 购买结果回调
}
}
public class TransactionProxy
{
private GameShop gameShop;
public TransactionProxy(GameShop gameShop)
{
this.gameShop = gameShop;
}
public void BuyProp(string name)//购买道具
{
Console.WriteLine("购买前的条件判断");
gameShop.BuyProp(name);
}
public void ExchangeProp(string name)//激活码兑换道具
{
Console.WriteLine("兑换前的条件判断");
gameShop.ExchangeProp(name);
}
public void RequestTransaction(int num)
{
//TODO 发起购买钻石请求的预处理
gameShop.RequestTransaction(num);
}
public void StopTransaction()
{
gameShop.StopTransaction();
//TODO 终止购买钻石请求之后的处理
}
}
其实静态代理缺点比较明显,就是静态代理代码冗余大,一单需要修改接口,代理类和委托类都需要修改。这个时候使用动态代理去弥补静态代理的缺点,在C#中可以使用Castle去实现动态代理的功能。
2.用动态代理模式重写
动态代理比起静态代理肯定会有性能方面的消耗,动态代理根本不用具体实现代理类,下面就是动态代理的代码:
public class GameShop : IGamePayment
{
public virtual void BuyProp(string name)//购买道具
{
Console.WriteLine("购买道具");
}
public virtual void ExchangeProp(string name)//激活码兑换道具
{
Console.WriteLine("兑换道具");
}
public virtual void RequestTransaction(int num)
{
//TODO 发起购买钻石请求
}
public virtual void StopTransaction()
{
//TODO 终止购买钻石请求
}
public virtual void TransactionResult(bool result)
{
//TODO 购买结果回调
}
}
public class Transaction : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (invocation.Method.Name == nameof(BuyProp))
{
BuyProp(invocation.Arguments[0].ToString());
invocation.Proceed();
}
else if (invocation.Method.Name == nameof(ExchangeProp))
{
ExchangeProp(invocation.Arguments[0].ToString());
invocation.Proceed();
}
else if (invocation.Method.Name == nameof(RequestTransaction))
{
RequestTransaction((int)invocation.Arguments[0]);
invocation.Proceed();
}
else if (invocation.Method.Name == nameof(StopTransaction))
{
invocation.Proceed();
StopTransaction();
}
}
public void BuyProp(string name)//购买道具
{
Console.WriteLine("购买前的条件判断");
}
public void ExchangeProp(string name)//激活码兑换道具
{
Console.WriteLine("兑换前的条件判断");
}
public void RequestTransaction(int num)
{
//TODO 发起购买钻石请求的预处理
}
public void StopTransaction()
{
//TODO 终止购买钻石请求之后的处理
}
}
以上就是动态代理的实现,动态代理其实就是对这个类的全部方法进行拦截,然后通过IInvocation里面的一些参数去判断具体拦截的情况,还有一点就是需要把被拦截的函数改成虚函数(virtual),接下来在Main函数里使用一下这个动态代理,具体代码如下:
GameShop GameShopProxy = new ProxyGenerator().
CreateClassProxy<GameShop>(new Transaction());
GameShopProxy.BuyProp("屠龙刀");
总结
1.代理模式优缺点
优点:1、职责清晰,高扩展性 2、代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。
缺点: 1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 2、我编不下去了,就算有缺点也是利大于弊,在这里提倡还是使用代理模式的。
2.代理模式和装饰器模式区别
相同点:都持有目标对象。
不同点:代理模式主要是对目标对象访问时的保护和权限的限制。装饰器模式主要是增加或加强对于目标对象的功能,装饰器的传送门:https://blog.csdn.net/m0_37920739/article/details/104397028
3.代理模式的使用场景
1)防止游戏外挂的代理类实现。
2)支付模块关于安全层的抽离。