videocache4cj构建者模式拆解HttpProxyCacheServerBuilder设计之美【免费下载链接】videocache4cj一个支持边播放边视频缓存库输入视频的URL就可方便快捷的实现视频边下边播功能项目地址: https://gitcode.com/Cangjie-TPC/videocache4cjvideocache4cj 是一个支持边播放边缓存的视频缓存库将视频 URL 交给它处理后设置给播放器即可实现视频边下载边播放。它的核心入口是HttpProxyCacheServerBuilder构建者类——这篇文章带你拆解 Builder 构建者模式在这套视频缓存库中的实现看清它是如何把缓存目录、清理策略、文件命名、请求头等 6 个配置参数优雅地封装进一次链式调用的。为什么视频缓存库需要构建者模式HttpProxyCacheServer内部要组装 6 个配置配置项作用默认值缓存目录 cacheRoot缓存文件存放位置应用独立缓存目录文件命名 fileNameGeneratorURL → 缓存文件名MD5 命名清理策略 diskUsage缓存满了怎么删512MB 按总大小 LRU元数据仓储 sourceInfoStorage记录 URL 与缓存文件的对应关系数据库实现请求头注入 headerInjector按 URL 附加自定义 Header空注入器运行上下文 context应用 StageContext必填如果直接用构造函数就要写一个 6 参数的长签名如果用可选参数 多次 setter又会出现对象先处于半初始化状态的中间态。构建者模式Builder Pattern就是为了解决这个问题✅链式调用每个配置方法返回this一行代码配完所有参数✅延迟构建调用build()之前对象只是一个配置草稿✅必填/选填分离只有context是必填的其余都有合理默认值构建者类全景一个 this 的循环之美打开 http_proxycache_server_builder.cj可以看到构建者的骨架非常清晰public class HttpProxyCacheServerBuilder { private let DEFAULT_MAX_SIZE: Int64 512 * 1024 * 1024 private var cacheRoot: String private var fileNameGenerator: ?FileNameGenerator None private var diskUsage: ?DiskUsage None private var sourceInfoStorage: ?SourceInfoStorage None private var headerInjector: ?HeaderInjector None private var context: StageContext }注意两个细节可选项全部是可选类型?前缀 初始值None表示用户没设置为build()阶段的兜底做准备构造函数只收必填的 context其余配置留给链式方法每个配置方法都遵循同一个三步曲存值 →return this→ 继续链。以设置缓存目录和缓存上限为例http_proxycache_server_builder.cjpublic func cacheDirectory(file: String): HttpProxyCacheServerBuilder { this.cacheRoot file return this } public func maxCacheSize(maxSize: Int64): HttpProxyCacheServerBuilder { this.diskUsage TotalSizeLruDiskUsage(maxSize) return this }这里还有一个巧思maxCacheSize和maxCacheFilesCount并不直接存数字而是在配置时就包装成对应的 LRU 策略对象totalsize_lru_diskusage.cj / totalcount_lru_diskusage.cj。构建者承担了把用户意图翻译成具体实现的职责调用方完全不用知道 LRU 类长什么样。build() 方法拆解默认值兜底为什么放在最后真正的精髓在 build() 方法public func build(): HttpProxyCacheServer { if (this.sourceInfoStorage.isNone()) { this.sourceInfoStorage SourceInfoStorageFactory.newSourceInfoStorage(this.context) } if (this.cacheRoot.size 1) { this.cacheRoot StorageUtils.getIndividualCacheDirectory() } if (this.diskUsage.isNone()) { this.diskUsage TotalSizeLruDiskUsage(this.DEFAULT_MAX_SIZE) } if (this.fileNameGenerator.isNone()) { this.fileNameGenerator Md5FileNameGenerator() } if (this.headerInjector.isNone()) { this.headerInjector EmptyHeadersInjector() } let config this.buildConfig() return HttpProxyCacheServer(config) }5 个if完成了默认值兜底凡是用户没配的项在这里统一填上缺省实现。源码中的注释还点破了一个关键设计决策之所以把初始化从构造函数改到 build是因为在构造函数里初始化之后若再调用 setDiskUsage旧的 diskUsage 对象仍会残留在 LruDiskUsage 调用 accept 方法时导致结果异常。也就是说把默认值补全推迟到build()就彻底避免了默认对象先被创建、又被新设置顶替却仍残留的中间态陷阱。这是构建者模式里非常值得学习的一处细节。兜底完成后buildConfig()把 5 个非空值一次性压进 Config 类——一个只有字段和构造函数的纯数据载体随后交给HttpProxyCacheServer完成最后的实例化。一次完整的链式调用长什么样来看 README.md 中的真实用法整个构建过程只有一行链式表达var server: HttpProxyCacheServer HttpProxyCacheServerBuilder(globalAbilityContext.getOrThrow()) .cacheDirectory(自定义缓存目录) .setFileNameGenerator(自定义文件命名规则类) .setHeaderInjector(自定义请求头类) .setDiskUsage(自定义缓存清理策略) .build()build()之后HttpProxyCacheServer会绑定一个随机端口并启动本地 HTTP 代理随后调一句getProxyUrl(原始URL, true)把返回的代理地址交给播放器边下边播就自动生效了。整个使用路径是构建者配置 → build() 兜底并生成 Config → 服务器持有 Config 启动代理 → 代理 URL 交给播放器每一步的类职责单一配置归配置Builder → Config运行归运行Server这就是 Builder 设计之美的落地。小结这套构建者设计好在哪易用调用方一行链式代码完成全部可配项未设置的项自动走安全默认值可扩展清理策略、命名规则、请求头全部面向抽象DiskUsage、FileNameGenerator、HeaderInjector替换实现不影响构建者️无中间态默认值集中在build()兜底杜绝了半初始化对象引发的清理策略误判配置与运行解耦不可变的 Config 是构建者与服务器之间的契约双方互不纠缠如果你是正在学习设计模式的开发者http_proxycache_server_builder.cj 这个 128 行的文件就是一个绝佳的构建者模式样本——短小、完整、每个决策都有注释交代。【免费下载链接】videocache4cj一个支持边播放边视频缓存库输入视频的URL就可方便快捷的实现视频边下边播功能项目地址: https://gitcode.com/Cangjie-TPC/videocache4cj创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?