Proxyパターン (3) - 仮想Proxy
『Rubyによるデザインパターン』(ラス・オルセン著 ピアソン・エデュケーション刊)の例をPythonに変換して書いています。目次
最後に、オブジェクトの生成を出来るだけ遅らせ、しかもそれをユーザーに気づかせない、仮想Proxyを作ります。
class VirtualAccountProxy(object): """「銀行口座」クラスの仮想Proxy""" def __init__(self, starting_balance): self._subject = None self.starting_balance = starting_balance def subject(self): if self._subject is None: self._subject = BankAccount(self.starting_balance) return self._subject def deposit(self, *a, **kw): return self.subject().deposit(*a, **kw) def withdraw(self, *a, **kw): return self.subject().withdraw(*a, **kw) def balance(self, *a, **kw): return self.subject().balance(*a, **kw) if __name__ == "__main__": proxy_list = [] for i in xrange(100000): proxy_list.append(VirtualAccountProxy(100)) #しばらくしてから・・・ proxy = proxy_list.pop() proxy.deposit(50) proxy.withdraw(10)
これで、いくつもVirtualAccountProxyを作ったとしても、
実際に必要になるまでBankAccountは生成されないので、
パフォーマンスを向上させることができます。
ところでこの例では、BankAccountの生成方法はVirtualAccountProxyの責任です。
これでは、BankAccountとVirtualAccountProxyの間の結合度を増してしまいます。
そこで、Strategyパターンを併用します。
class VirtualAccountProxy(object): def __init__(self, creation_callable): self._subject = None self.creation_callable = creation_callable def subject(self): if self._subject is None: self._subject = creation_callable() return self._subject #以下同様
BankAccountの生成はcreation_callableに委譲します。
ProxyパターンはAdapterパターンに良く似ています。
どちらも他のオブジェクトのためのパターンです。
しかし、Adapterがオブジェクトのインターフェイスを変更するのに対し、
Proxyはオブジェクトへのアクセスを制御します。