Unity 代理模式

初学者,自用笔记

用于在不改变目标对象对外接口的前提下,通过一个替身对象(Proxy)来控制对目标对象的访问:比如延迟加载、权限校验、网络转发、线程切换、缓存、日志与性能统计等。

  • Subject/IChunk(抽象主题/服务接口):目标与代理共同实现的接口(例如 IAssetProvider、IService、- IRepository)。
  • RealSubject/RealChunk(真实主题/实际服务):真正干活的对象(例如真实资源加载器、真实网络服务、真实存档仓库)。
  • Proxy(代理):实现同一 Subject 接口,内部持有 RealSubject(或其创建方式),在转发前后附加控制逻辑。实现方法有虚代理、保护代理、远程代理等等......

简单例子

ICkunk

// Subject:服务接口(调用方只依赖它)
public interface IProfileService
{
    Task<string> GetPlayerNameAsync();
}

RealChunk

// RealSubject:真实服务(真正干活,可能初始化很重)
public sealed class RealProfileService : IProfileService
{
    public RealProfileService()
    {
        // 假设初始化很重(网络/缓存/鉴权等)
        Console.WriteLine("[RealProfileService] init heavy stuff...");
    }

    public async Task<string> GetPlayerNameAsync()
    {
        await Task.Delay(100); // 模拟网络/IO
        return "Alice";
    }
}

Proxy

代理(Proxy)这个中间层的核心价值是:不改调用方代码、不改(或尽量少改)真实服务代码,但能在访问真实对象前后插入控制逻辑,并且在类型层面做到可替换(接口不变)

// Proxy:代理(同接口,控制访问:懒加载 + 可附加日志/缓存/校验)
public sealed class ProfileServiceProxy : IProfileService
{
    private RealProfileService _real;

    public async Task<string> GetPlayerNameAsync()
    {
        // 虚代理:用到才创建真实对象
        _real ??= new RealProfileService();

        Console.WriteLine("[Proxy] Before call");
        var name = await _real.GetPlayerNameAsync();
        Console.WriteLine("[Proxy] After call");

        return name;
    }
}

Client

// Client:调用方(不关心是真实服务还是代理)
public static class ProxyDemo
{
    public static async Task Main()
    {
        IProfileService service = new ProfileServiceProxy();

        // 第一次调用才触发 RealProfileService 的初始化
        var name = await service.GetPlayerNameAsync();
        Console.WriteLine($"PlayerName = {name}");
    }
}
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务