代理模式(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
Rails
中 ActiveRecord::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)代理
使几个用户能够同时使用一个对象而没有冲突。
缺点
-
由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢
-
实现代理模式需要额外的工作