Design pattern that is highly reusable. Simple handlers implement one specific task from a complex set of tasks to be performed on an object. Such handlers can then be layered in a stack, in different combinations, together achieving complex processing of an object. New handlers are easy to implement and add.
Python, 68 lines
A good way to divide a set of operations or tasks that can be performed on an object into smaller, simpler handlers. Each handler implements only one task and several handlers can be reused in different configurations in order to implement a complex functionality. New handlers are easy to implement because they only override one or several hook methods from a base class, and the base class takes care of generic functionality.
Reusability is the big reason for using this pattern. For instance, a file filter can be reused with many other handlers that perform a task on files. And a set of small, specific filters can be layered together into more complex filters.
The mechanism chosen to append handlers to each other is to override the __add__ operator. This allows great flexibility in how handlers can be layered in the stack. For example,<pre> hStack = hInst1 + hInst2 + hInst3</pre> creates hStack from three instances of Handler subclasses. The same result would be achieved by:<pre> hInst1 + hInst2 + hInst3 hStack = hInst1</pre> Even more, the same result is achieved by:<pre> hStack = hInst1 hStack + hInst2 hStack + hInst3</pre> or by:<pre> hInst2 + hInst3 hStack = hInst1 + hInst2</pre> or even by: <pre> hStack = hInst1 + hInst2 hInst2 + hInst3</pre> The attribute 'data' in class Handler is a dictionary object that is shared by all the handlers in the stack. The __add__ operator ensures that. Data can be passed from a handler to handlers above it in the stack by writing entries in self.data.
A hook method can return a value of 'False' and thus act as a filter by blocking the handlers above it from processing the object. If it returns a value of 'True', a handler also has the ability to pass additional data to the handlers above it in the stack. Although the wrapper methods (useHook in this example) are invoked top-down, the hook methods are effectively invoked bottom-up and data can be passed only in that direction.
Note to the editors: this code snippet is the basic idea behind an open-source project that I am working on and that I "own" (see http://pyfmf.sourceforge.net). If the recipe is approved, I would appreciate it if the project would also be mentioned.