Implementing chain of responsibility

Chris Rebert clp2 at rebertia.com
Mon Mar 9 12:20:06 CET 2009


On Mon, Mar 9, 2009 at 3:54 AM, koranthala <koranthala at gmail.com> wrote:
> On Mar 9, 12:16 pm, Chris Rebert <c... at rebertia.com> wrote:
>> On Sun, Mar 8, 2009 at 11:53 PM, koranthala <koranth... at gmail.com> wrote:
>> > Hi,
>> >    I want to implement chain of responsibility pattern in Python (for
>> > a Django project)
>> >    The problem that I see is a rather odd one - how to link the
>> > subclasses with the super class.
>>
>> Grabbing out my copy of Head First Design Patterns and looking up this
>> pattern, it sounds like you're going about this the wrong way. From
>> what I can grok, Chain-of-Responsibility looks like this:
>>
>> class SomeHandler(object)
>>     def __init__(self, successor=None):
>>         self.successor = successor
>>
>>     def theMethod(self, theRequest):
>>         result = try_and_handle(theRequest)
>>         if did_not_handle(theRequest) and self.successor is not None:
>>             return successor.theMethod(theRequest)
>>         else:
>>             return result
>>
>> #imagine some other handler classes
>> #setup:
>> masterHandler = SomeHandler(OtherHandler(ThirdHandler()))
>> #usage:
>> result = masterHandler.theMethod(aRequest)
>>
>> So the *classes* don't ever know anything about each other; you pass a
>> handler class an instance of its successor handler at
>> construction-time. So there's no need for any registry or
>> introspection at all. You determine the ordering at runtime when you
>> construct the instances.
>>
>> Of course, this entire pattern is usually unnecessary in Python as you
>> can usually write the same thing less verbosely and more
>> straightforwardly as:
>> def someHandler(theRequest):
>>     result = try_and_handle(theRequest)
>>     if did_not_handle(theRequest):
>>         return False, None
>>     else:
>>         return True, result
>>
>> #imagine some other handler functions
>> #setup:
>> handlers = [someHandler, otherHandler, thirdHandler]
>> #usage:
>> for handler in handlers:
>>     success, result = handler(theRequest)
>>     if success: break
>>
>> Note the lack of classes and how the sequencing is now made explicit.
>>
>> Cheers,
>> Chris
>>
>> --
>> I have a blog:http://blog.rebertia.com
>
> Hi,
>    Thank you very much Chris for the extremely quick and helpful
> reply.
>    I agree that it is not perfect CoR as per the examples given. But,
> I have done it very similar to the second example that you had given.
> I needed classes because I am not doing just one thing - I have a lot
> of pre-processing and post processing, so I had used classes. The
> register methods etc are just a fancy way of creating the list as you
> mentioned. I am using the registry because there are many procedures
> wherein different methods of the classes in registry are being used.
>    I am not sure whether I have understood your points completely. I
> still cannot understand how to do the import so that the register
> methods are hit.

The relationship should be between *instances* of the classes, not
among the *classes themselves directly*.
Each class is supposed to have a 'successor' instance variable that
its instances will delegate to if necessary. Reread my first code
sample and note how the "chain" is forged in the creation of
`masterHandler`.

Cheers,
Chris

-- 
I have a blog:
http://blog.rebertia.com



More information about the Python-list mailing list