一、代理模式概述
代理模式(Proxy Pattern)是一种结构型设计模式,其核心思想是通过引入一个“代理对象”来控制对“目标对象”的访问。
在这种模式中,代理对象与目标对象实现相同的接口,客户端通过调用代理对象的方法间接访问目标对象。代理对象可以在调用目标对象的方法前后添加额外逻辑(如权限校验、日志记录、缓存处理等),而无需修改目标对象本身,从而实现对目标对象的增强或保护。
代理模式的核心角色包括:

二、代理模式的使用场景
三、代理模式的优缺点
优点
缺点
四、使用代理模式的注意事项
五、示例代码
using System;
// 抽象主题接口
public interface ISubject
{
void Request();
}
// 真实主题类(被代理对象)
public class RealSubject : ISubject
{
public void Request()
{
Console.WriteLine("真实主题执行核心业务逻辑");
}
}
// 代理类
public class Proxy : ISubject
{
private readonly ISubject _realSubject;
// 初始化时创建真实主题实例(也可通过构造函数注入)
public Proxy()
{
_realSubject = new RealSubject();
}
public void Request()
{
// 代理前置处理
PreRequest();
// 调用真实主题的核心逻辑
_realSubject.Request();
// 代理后置处理
PostRequest();
}
// 代理前置增强逻辑
private void PreRequest()
{
Console.WriteLine("代理:执行前置处理(如权限验证、日志记录)");
}
// 代理后置增强逻辑
private void PostRequest()
{
Console.WriteLine("代理:执行后置处理(如结果缓存、资源释放)");
}
}
// 客户端调用示例
public class Client
{
public static void Main()
{
// 客户端通过代理访问真实主题,无需直接依赖真实主题
ISubject proxy = new Proxy();
proxy.Request();
}
}
六、代理模式在特来电的应用
1.HSF(High Service Framework),特来电的三大核心框架之一。通过远程服务代理,实现不同模块之间的服务通信。
2.服务降级组件。通过代理模式,实现依赖服务的多级降级功能。代码如下:
//抽象代理类
using System;
using Teld.CCP.Foundation.Spi.MultiTargetContainer;
namespace Teld.CCP.Foundation.Service.MultiTargetContainer.Middleware;
public abstract class AbstractMiddlewareContainer : AbstractServiceContainer where T : class
{
public override AbstractProxy AddService(T service, IRouterFactory factory)
{
AbstractProxy abstractProxy = base.AddService(service, factory);
MiddlewareProxy nextProxy = abstractProxy as MiddlewareProxy;
if (base.ProxyServices.Count - 2 >= 0 && base.ProxyServices[base.ProxyServices.Count - 2] is MiddlewareProxy middlewareProxy)
{
middlewareProxy.SetNextProxy(nextProxy);
}
return abstractProxy;
}
public T1 ProxyInvoke(Func func)
{
AbstractProxy proxy = GetProxy();
T arg = proxy as T;
return func(arg);
}
}
//实现类
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Teld.Boss.CSMSDK.Models;
using Teld.CCP.Foundation.Service.MultiTargetContainer;
using Teld.CCP.Foundation.Service.MultiTargetContainer.Middleware;
namespace Teld.Boss.CSMSDK.Bill
{
public class BillStationQueryContainer : AbstractMiddlewareContainer
{
private static BillStationQueryContainer container;
private readonly static object locker = new object();
private BillStationQueryContainer()
{
AddService(new SGBillStationQuery(), null);
AddService(new DBBillStationQuery(), null);
}
///
/// 获取实例
///
///
public static BillStationQueryContainer GetInstance()
{
if (container == null)
{
lock (locker)
{
if (container == null)
{
container = new BillStationQueryContainer();
}
}
}
return container;
}
///
/// 创建代理
///
///
///
public override AbstractProxy CreateProxy(IBillStationQuery service)
{
return new BillStationQueryProxy(service);
}
///
/// 查询互联互通电站信息
///
///
///
public HlhtStationInfoVM GetHlhtStationInfo(HlhtStationQueryParms parms, string sqlMapName, CustomParam customParam = null)
{
var result = ProxyInvoke((P) =>
{
return P.GetHlhtStationInfo(parms, sqlMapName, customParam);
});
return result;
}
}
}
//SG调用实现
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Teld.Boss.CSMSDK.Models;
using Teld.Core.ServiceGateway.Client;
namespace Teld.Boss.CSMSDK.Bill
{
public class SGBillStationQuery : IBillStationQuery
{
/// 互联互通电站查询
public HlhtStationInfoVM GetHlhtStationInfo(HlhtStationQueryParms parms, string sqlMapName, CustomParam customParam)
{
if (parms == null) return null;
Dictionary filter = new Dictionary();
filter.Add("filter", JsonConvert.SerializeObject(parms));
var response = new SGHttpClient(true).PostMainIDC("CSM-GetHlhtStationInfo", filter, 3);
return response.data;
}
}
}
//DB查询实现
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Teld.Boss.CSMSDK.DataAccess;
using Teld.Boss.CSMSDK.Models;
using Teld.Core.Kernel.Service;
namespace Teld.Boss.CSMSDK.Bill
{
public class DBBillStationQuery : IBillStationQuery
{
/// 互联互通电站查询
public HlhtStationInfoVM GetHlhtStationInfo(HlhtStationQueryParms parms, string sqlMapName, CustomParam customParam)
{
if (parms == null || string.IsNullOrWhiteSpace(sqlMapName)) return null;
if (customParam == null) customParam = new CustomParam();
var dao = DaoFactory.GetDao(sqlMapName);
parms.StaTableName = customParam.StaTableName;
parms.PileTableName = customParam.PileTableName;
parms.StaExTableName = customParam.StaExTableName;
return dao.GetHlhtStationInfo(parms);
}
}
七、总结思考
代理模式通过引入代理对象实现了对目标对象的间接访问,其核心价值在于在不修改目标对象的前提下,灵活添加附加功能,同时保证客户端对目标对象的透明访问。
从实践角度看,代理模式的优势在于职责分离和扩展性——目标对象专注于业务逻辑,代理对象处理非业务逻辑(如日志、权限),当需求变化时(如新增缓存功能),只需新增代理类即可,无需改动原有代码。
但需注意,代理模式会增加系统的复杂度和性能开销,因此不宜过度使用。在实际开发中,可结合具体场景选择代理类型(如远程调用用远程代理,权限控制用保护代理),并通过 AOP 技术(如动态代理)减少手动编写代理的冗余代码。
总体而言,代理模式是解决“对象访问控制”和“功能增强”问题的有效方案,合理使用可显著提升系统的可维护性和灵活性。