Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Recently I wrote two Java programs (for Microsoft Windows OS) that must catch global keyboard events generated by other applications concurrently running on the same desktop. Microsoft provides a way to do that by registering the programs as a global keyboard hook listener. Coding did not take long, but debugging did. The two programs seemed to work fine when tested separately, but failed when tested together. Further tests revealed that when the two programs ran together, the program that launched first was always unable to catch the global key events, but the application launched later worked just fine.
I resolved the mystery after reading the Microsoft documentation. The code that registers the program itself as a hook listener was missing the CallNextHookEx() call required by the hook framework. The documentation reads that each hook listener is added to a hook chain in the order
of startup; the last listener started will be on the top. Events are sent to the first listener in the chain. To allow all
listeners to receive events, each listener must make the CallNextHookEx() call to relay the events to the listener next to it. If any listener forgets to do so, the subsequent listeners will not
get the events; as a result, their designed functions will not work. That was the exact reason why my second program worked
but the first didn't!
The mystery was solved, but I was unhappy with the hook framework. First, it requires me to "remember" to insert the CallNextHookEx() method call into my code. Second, my program could disable other programs and vise versa. Why does that happen? Because Microsoft
implemented the global hook framework following exactly the classic Chain of Responsibility (CoR) pattern defined by the Gang of Four (GoF).
In this article, I discuss the loophole of the CoR implementation suggested by GoF and propose a solution to it. That may help you avoid the same problem when you create your own CoR framework.
The classic CoR pattern defined by GoF in Design Patterns:
"Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it."
Figure 1 illustrates the class diagram.

Figure 1. CoR class diagram
A typical object structure might look like Figure 2.
Figure 2. CoR object structure
From the above illustrations, we can summarize that:
The code segments below demonstrate the difference between requester code that uses CoR and requester code that doesn't.
Archived Discussions (Read only)
(