SpecialistOff.NET / Вопросы / Статьи / Фрагменты кода / Резюме / Метки / Помощь / Файлы

Назад

State


Метки: python

The State pattern adds more implementations to Proxy, along with a way to switch from one implementation to another during the lifetime of the surrogate:

# Fronting/StateDemo.py
# Simple demonstration of the State pattern.

class State_d:
    def __init__(self, imp):
        self.__implementation = imp
    def changeImp(self, newImp):
        self.__implementation = newImp
    # Delegate calls to the implementation:
    def __getattr__(self, name):
        return getattr(self.__implementation, name)

class Implementation1:
    def f(self):
        print("Fiddle de dum, Fiddle de dee,")
    def g(self):
        print("Eric the half a bee.")
    def h(self):
        print("Ho ho ho, tee hee hee,")

class Implementation2:
    def f(self):
        print("We're Knights of the Round Table.")
    def g(self):
        print("We dance whene'er we're able.")
    def h(self):
        print("We do routines and chorus scenes")

def run(b):
    b.f()
    b.g()
    b.h()
    b.g()

b = State_d(Implementation1())
run(b)
b.changeImp(Implementation2())
run(b)

You can see that the first implementation is used for a bit, then the second implementation is swapped in and that is used.

The difference between Proxy and State is in the problems that are solved. The common uses for Proxy as described in Design Patterns are:

  1. Remote proxy. This proxies for an object in a different address space. A remote proxy is created for you automatically by the RMI compiler rmicas it creates stubs and skeletons.
  2. Virtual proxy. This provides “lazy initialization” to create expensive objects on demand.
  3. Protection proxy. Used when you don’t want the client programmer to have full access to the proxied object.
  4. Smart reference. To add additional actions when the proxied object is accessed. For example, or to keep track of the number of references that are held for a particular object, in order to implement the copy-on-write idiom and prevent object aliasing. A simpler example is keeping track of the number of calls to a particular method.

You could look at a Python reference as a kind of protection proxy, since it controls access to the actual object on the heap (and ensures, for example, that you don’t use a null reference).

[[ Rewrite this: In Design PatternsProxy and State are not seen as related to each other because the two are given (what I consider arbitrarily) different structures. State, in particular, uses a separate implementation hierarchy but this seems to me to be unnecessary unless you have decided that the implementation is not under your control (certainly a possibility, but if you own all the code there seems to be no reason not to benefit from the elegance and helpfulness of the single base class). In addition, Proxy need not use the same base class for its implementation, as long as the proxy object is controlling access to the object it “fronting” for. Regardless of the specifics, in both Proxy and State a surrogate is passing method calls through to an implementation object.]]]