设计模式  

代理模式(Proxy Pattern)

意图(GOF)

Provide a surrogate or placeholder for another object to control access to it.(为其他对象提供一种代理以控制对这个对象的访问)

使用场景

虚拟代理(Virtual Proxy)

作为创建开销大的对象的代表;虚拟代理经常直到我们真正需要一个对象的时候才创建它;当对象在创建前或创建中时,由虚拟代理来扮演对象的替身;对象创建后,代理就会将请求直接委托给对象;

示例: Document -> LazyLoadImage –> Image

class Document
  attr_accessor :elements

  def load
    elements.each { |el| el.load }
  end

  def render
    elements.each { |el| el.render }
  end
end

class Image
  def load
    # load image
  end

  def render
    # render loaded image
  end
end

class LazyLoadImage
  attr_reader :image

  def initialize
    @image = Image.new
  end

  def load
  end

  def render
    image.load
    image.render
  end
end

document = Document.new
#document.elements.push(Image.new)
document.elements.push(LazyLoadImage.new)
document.load
document.render

RailsActiveRecord::Associations::CollectionProxy 就是虚拟代理一个相当不错的示例。

保护代理(Protection Proxy)

可以控制对真实对象的使用权限。

示例:

class File
  def self.create(name)
    # creating file
  end

  def self.delete(name)
    # deleting file
  end
end

class FileProxy
  def self.create(user, file_name)
    raise 'Only Admin Can Create File' unless user.admin?

    File.create(file_name)
  end

  def self.delete(user, file_name)
    raise 'Only Admin Can Delete Files' unless user.admin?

    File.delete(file_name)
  end
end

远程代理(Remote Proxy)

为一个位于不同的地址空间的对象提供一个本地的代理对象

示例:

class ShortUrlServer
  def self.shorten(url)
    Net::HTTP.post_form('http://www.shorten.com/', url: url).body
  end
end

智能引用代理(Smart Reference)

当一个对象被引用时,提供一些额外的操作。

示例:

class Service
  def get_quote(params)
    # send request
  end
end

class ServiceWithLog
  def get_quote(params)
    puts "Getting quote with params: #{params}"

    service.get_quote(params)
  end

  private

  def service
    @service ||= ServiceWithLog.new
  end
end

COW代理

它是一种特殊的虚拟代理,把复制(克隆)操作延迟到只有在客户端真正需要时才执行。

缓冲(Cache)代理

为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。

防火墙(Firewall)代理

保护目标不让恶意用户接近。

同步化(Synchronization)代理

使几个用户能够同时使用一个对象而没有冲突。

缺点

  1. 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢

  2. 实现代理模式需要额外的工作

© 2019 - 2020 · GenkinHe Powered by [Hugo] ·