Using Proxy and Chain of Responsibility (and almost Flyweight)
Write a program that has a GUI full of buttons. Let's make
it a 15x15 square with 225 buttons. Each button will have a
non-negative integer on it as label. You can generate
consecutive integers starting at 0, up to 224.
When the user clicks on a button (you can handle left-clicks only)
the label (number) is sent to a chain of responsibility for handling.
You can use the "incorrect" flyweight example that I showed in
class as the GUI code you use/modify. Actually, the correct one will
work as well here.
The chain will have 3 processors in it (in this order):
a prime handler, an odd handler, and an even handler.
It will be a basic chain, where once a processor decides it can
handle the event (number/label), it does not pass the event
further along the chain.
- prime handler PH:
if the button number is prime, PH will handle it
by always sending the number across the network to another
process (we will call it PP). PP will compute some function
from the number (make up whatever deterministic function you
want) and send back the result to PH. PH will use a proxy
to encapsulate the network. PP will similarly have a net
proxy in it. Use the "netServer" proxy example I showed in
class as a coding guide.
The button number and result computed by PP will be reported by PH
in a popup window; in this window, also put some note saying
the the result was computed remotely.
- odd handler OH:
if the button number is odd (and not prime, since OH is after
PH in the chain), OH will handle it by *sometimes* sending the
number across the network to another process (let's call it OP).
OP will compute some non-deterministic function (see below
for function information) from the button number and send the
result back to OH.
As with PH/PP, OH and OP will each have a net proxy.
OH will also have a server proxy to decide whether or not
to send the button number out over the network.
The OH server proxy will cache the results that come back
from OP so that if the network is not needed, the
previously computed result can be reported.
The cache will save the previous result for each button number.
The decision to go remote or not will be made based on wall
clock: if the previous result for the button number was obtained
in the last 30 seconds, use it; if it is older than 30 seconds,
go out over the net and get a new result.
The function computed by OP can be anything you find entertaining
as long as it is non-deterministic; this means it returns a possibly
different value every time it is called on a button number.
For example, if we call it with button 9, we might get a result
of 17. If we call it again with button 9, we might get something
else, like 43, as a result. Maybe something involving system
clock would be fun. Use your imagination.
The button number and result computed by OP will be reported
by OH in a popup window; in this window, also put some note saying
whether the result was computed remotely or obtained from the
local cache.
- even handler EH:
if the button number is even EH will handle it by some
local computation in EH. Make up any function you find
entertaining to compute from the button number with these
constraints: the function returns a positive integer, and the
function is deterministic (each call with, say, button number
8 will produce the same result).
No net proxy is needed, but a server proxy is needed.
The proxy will reject any request from a button number that
is a multiple of 6. In this case, return the value -1.
You might find the example "simpleServer" easier to use
for this case, as it does not have the net proxy
included in it.
EH will report the button number and result computed in a
popup window (a possible result to report is that the proxy
rejected the request); also put in some note saying the result
was computed locally.
As mentioned above, the class example programs for
flyweight, simpleServer, and netServer are there to use
as coding guides for the patterns.
You will have three processes running in the final product:
the GUI with proxy chain, PP, and OP; you will use two
sockets (via net proxies): one for PH to PP communications,
and the other for OH to OP communications.