Unity游戏开发设计模式——代理模式

代理模式

请添加图片描述

代理模式是一种结构型设计模式, 让你能够提供对象的替代品或其占位符。 代理控制着对于原对象的访问, 并允许在将请求提交给对象前后进行一些处理。

结构

代理模式的结构比较简单。为了让客户端能够一致地对待真实对象和代理对象,我们引入了抽象层。

请添加图片描述

需求&差代码

在你的游戏里,你负责开发一个联机的类塞尔达相簿系统。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W7ge9P23-1676261446330)(null)]

这些图片都是存在服务端的,现在要求你开发一个ImgDownloader,把接口给UI制作人员以供他调用。

public class ImgDownloader{
    public bool DownLoadImg(int id){
        //把id发给后端,等后端把文件流传回来,再把文件流写入相册
         return true;
    }
}

你三下五除二写好了,接口也给出去了,测试都测好了。

结果服务端找过来了。

服务端:“欸大哥,你这玩意儿性能开销有点大啊。玩家每次点击图片你都给下载,我服务器都要被搞挂了。你加个缓存机制吧”

你:”有道理,策划怎么也不提要做个缓存呢?考虑地太浅啦!都怪策划“

扫描二维码关注公众号,回复: 14587272 查看本文章

服务端:”对对对,都怪策划,你给加个缓存吧“

请添加图片描述

于是你准备加个缓存字典,大概是这样的。

public class ImgDownloader
    {
        private Dictionary<int, bool> downloadCache;
        private ImgDownloader()
        {
            downloadCache = new Dictionary<int, bool>();
        }
        /// <summary>
        /// 下载图片
        /// </summary>
        /// <param name="id">图片id</param>
        /// <returns></returns>
        public bool DownLoadImg(int id)
        {
            bool downloaded = false;
            downloadCache.TryGetValue(id, out downloaded);
            if (downloaded)
            {
                // 已经下载过,无需重复下载
                return false;
            }
            //把id发给后端,等后端把文件流传回来,再把文件流写入相册
            return true;
        }
    }

这时候测试不乐意了。

测试:“大哥,我都测好了,你全部重新改一轮我得全部重新测一遍啊”

你:“我只是加个缓存,其他地方都不改的你不测也行”

测试:“我不信,上次你说你就改个配置,结果不小心动了行别的代码,线上出了P0 BUG我还被领导批了呢”

你:“我想想啊,我接口都不改,用代理模式引入一个缓存代理做缓存用,这样下载相关的逻辑肯定不会被改到了”

好代码(用代理模式实现需求)

请添加图片描述

摘录部分代码:

public class DownloadCacher : IDownloader
{
    private Dictionary<int, bool> _cache;
    private ImgDownloader _imgDownloader;
    public DownloadCacher()
    {
        _imgDownloader = new ImgDownloader();
        _cache = new Dictionary<int, bool>();
    }

    public bool DownloadImg(int id)
    {
        bool downloaded = false;
        _cache.TryGetValue(id, out downloaded);
        if (!downloaded)
        {
            return _imgDownloader.DownloadImg(id);
        }
        else
        {
            return false;
        }
    }
}

调用:

// 示例代码
IDownloader downloader = new DownloadCacher();
downloader.DownloadImg(1);

常用例子

  • 虚拟代理—延迟初始化

    如果你有一个偶尔使用的重量级服务对象, 一直保持该对象运行会消耗系统资源时, 可使用代理模式。

  • 缓存代理。适用于需要缓存客户请求结果并对缓存生命周期进行管理时, 特别是当返回结果的体积非常大时。

​ 例如一个视频下载类,正常它没有缓存功能。我们添加一个公共接口,再引入一个代理类,在代理里实现缓存功能

  • 日志代理。

    适用于需要保存请求记录时。

  • 远程代理。

    本地执行远程代码。

  • 智能引用代理。

    代理可以将引用记录在案,提供一些额外操作如是否仍在运行/是否被修改了/是否可复用/被调用次数。

  • 保护代理——访问控制

优点

  • 开闭原则

    不修改服务或客户端就能创建新代理

源码

完整代码已上传至nickpansh/Unity-Design-Pattern | GitHub

其他设计模式

专题 | Unity3D游戏开发中的设计模式 | 问渠 (wenqu.site)

猜你喜欢

转载自blog.csdn.net/nick1992111/article/details/129006790
今日推荐