实际实际上建立在一个善意的谎言之上。当客户向我们要求一个对象的时候,我们的确将一个对象返回给客户。然而我们返回的对象却不是客户要求的那个对象,我们所返回的对象虽然在行为上和客户要求的一样,但是那个对象实际上只是一个替身。这个冒充的对象称作代理
代理的内部隐藏着一个指向真实对象的引用。当客户调用代理的方法时,这个代理就将请求转发给真实对象。 -------《Ruby 设计模式》
一下情形都可以使用代理模式,另外,本文最后,我们看看Ruby实现代理模式是何其简洁!
例1:代理的基本实现方法
#银行账户类
class BankAccount
attr_accessor :balance
def initialize(starting_blance=0)
@balance=starting_blance
end
def deposit(amount)
@balance+=amount
end
def withdraw(amount)
@balance-=amount
end
end
#银行账户代理类
class BankAccountHandle
def initialize(real_object)
@real_object=real_object
end
def deposit(amount)
@real_object.deposit(amount)
end
def balance
@real_object.balance
end
end
表面上看,代理类只是封装了真实对象,有点多此一举,但事实并非如此,当我们需要对真实的银行账户对象添加一些安全控制的时候,显然只需要在代理类里面添加部分代码即可。虽然这些访问控制也可以在原来的银行账户类里面做,但这将可变与不变的部分交织在了一起,不符合设计模式的基本原则。
例2:有时我们已经有了一个设计好的类,但我们需要把它放入另外一个工程中直接使用,而不是从造车轮,那么代理模式显然派上了用场。只需将原有类的一个对象作为当前项目类的一个成员变量即可。剩下的封装函数你也应该知道怎么做了
例3:代理可以将对象的创建推迟到最后,我们有时并不需要一开始就创建一大堆对象,我们想用到的时候再说吧。那么用代理模式就很容易实现。
例如重写上面的BankAccountHandle
class BankAccountHandle
def initialize(starting_balance=0)
@balance=starting_balance
end
def deposit(amount)
s=subject
return s.deposit(amount)
end
def subject
return @subject || (@subject=BankAccount.new( balance ))
end
end
例4:利用Ruby的method_missing方法实现代理的简洁版
重写上面的BankAccountHandle
class BankAccountHandle
def initialize(real_object)
@real_object=real_object
end
def method_missing(name,*args)
@real_object.send(name,*args) #来啥方法调用啥方法,不需要一个挨一个的写real_object的各个方法
end
end
注:我比较喜欢这个模式,希望对大家有所启发。有喜欢的设计模式的童鞋们欢迎交流批评指正。:-)
策略模式:
模板方法: