Go设计模式之代理模式图文详解

  // 远程服务接口。

  interface ThirdPartyTVLib is

  method listVideos()

  method getVideoInfo(id)

  method downloadVideo(id)

  // 服务连接器的具体实现。该类的方法可以向腾讯视频请求信息。请求速度取决于

  // 用户和腾讯视频的互联网连接情况。如果同时发送大量请求,即使所请求的信息

  // 一模一样,程序的速度依然会减慢。

  class ThirdPartyTVClass implements ThirdPartyTVLib is

  method listVideos() is

  // 向腾讯视频发送一个 API 请求。

  method getVideoInfo(id) is

  // 获取某个视频的元数据。

  method downloadVideo(id) is

  // 从腾讯视频下载一个视频文件。

  // 为了节省网络带宽,我们可以将请求结果缓存下来并保存一段时间。但你可能无

  // 法直接将这些代码放入服务类中。比如该类可能是第三方程序库的一部分或其签

  // 名是`final(最终)`。因此我们会在一个实现了服务类接口的新代理类中放入

  // 缓存代码。当代理类接收到真实请求后,才会将其委派给服务对象。

  class CachedTVClass implements ThirdPartyTVLib is

  private field service: ThirdPartyTVLib

  private field listCache, videoCache

  field needReset

  constructor CachedTVClass(service: ThirdPartyTVLib) is

  this.service = service

  method listVideos() is

  if (listCache == null || needReset)

  listCache = service.listVideos()

  return listCache

  method getVideoInfo(id) is

  if (videoCache == null || needReset)

  videoCache = service.getVideoInfo(id)

  return videoCache

  method downloadVideo(id) is

  if (!downloadExists(id) || needReset)

  service.downloadVideo(id)

  // 之前直接与服务对象交互的 GUI 类不需要改变,前提是它仅通过接口与服务对

  // 象交互。我们可以安全地传递一个代理对象来代替真实服务对象,因为它们都实

  // 现了相同的接口。

  class TVManager is

  protected field service: ThirdPartyTVLib

  constructor TVManager(service: ThirdPartyTVLib) is

  this.service = service

  method renderVideoPage(id) is

  info = service.getVideoInfo(id)

  // 渲染视频页面。

  method renderListPanel() is

  list = service.listVideos()

  // 渲染视频缩略图列表。

  method reactOnUserInput() is

  renderVideoPage()

  renderListPanel()

  // 程序可在运行时对代理进行配置。

  class Application is

  method init() is

  aTVService = new ThirdPartyTVClass()

  aTVProxy = new CachedTVClass(aTVService)

  manager = new TVManager(aTVProxy)

  manager.reactOnUserInput()