Another two examples of using changing classes

Duncan Booth duncan at NOSPAMrcp.co.uk
Tue Aug 14 04:22:12 EDT 2001


"Terry Reedy" <tjreedy at home.com> wrote in 
news:O_0e7.101053$EP6.25883351 at news1.rdc2.pa.home.com:

>> I have a proxy class that forwards network requests to a remote
>> server. When it gets disconnected, it still needs to respond to
>> commands, albeit with failure responses.
>>
>> However, if a certains commands are given to the instance it can
>> reconnect and start working normally again.
>>
>> The other way to do this is to have two classes - Connected and
>> Disconnected, and the instance switches between the classes to change
>> the way it works. Doing this without changing classes would require
>> having a frontend instance and a changing backend instance, and double
>> the number of function calls done with every operation. 
> 
> A third way is to have a 'connected' variable and make every function
> conditional on the state variable.  Changing class is much cleaner.

And for those who have read the Gang of Four book, this is the State 
pattern which replaces the state variable and tests everywhere with a 
helper class for each state and forwarding each method to the current 
helper class. They also note that for languages that support it, another (I 
can't remember if they say better) way is to change the class of the object 
to reflect the state directly.

I would think that the two most Pythonic ways to implement the State 
pattern would be to either have a base class with the common behaviour, and 
one derived class for each state, mutating the actual class to follow the 
current state, or simply have some helper classes with the state specific 
methods and update the instance's dictionary on state change.

Somehow the C++ish alternative of forwarding all the methods doesn't appeal 
(even though in Python you could do the forwarding once in __getattr__), 
and the state variable really sucks.

-- 
Duncan Booth                                             duncan at rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?



More information about the Python-list mailing list