This library provides an abstraction for building an instance of the proxy design pattern. The pattern consists of two objects, a host and a surrogate object. The host object delegates method calls to its surrogate object. Each host has a dynamically assigned surrogate, so an object can completely change its behavior merely by changing the surrogate.
The library provides a form, surrogate
:
(surrogate
(method-name arg-spec ...) ...
)
SYNTAX
where
arg-spec ::== | (id ...) | id
The surrogate form produces four values: a host mixin (a procedure that accepts and returns a class), a host interface, a surrogate class, and a surrogate interface, in that order.
The host mixin adds one additional
field, surrogate
, to its argument and a getter
method, get-surrogate
, and a setter
method, set-surrogate
, for changing the
field. The set-surrogate
form accepts instances the
class returned by the form or #f
, and updates the
field with its argument. Then, it calls the
on-disable-surrogate
on the previous value of the
field and on-enable-surrogate
for the new value of
the field. The get-surrogate
method returns the
current value of the field.
The host mixin has a single overriding method for each
method-name
in the surrogate
form. Each of
these methods is defined with a case-lambda with one arm for
each
arg-spec
. Each arm has the variables as arguments
in the arg-spec
. The body of each method test the
surrogate
field. If it is #f
, the method
just returns the result of invoking the super method. If the
surrogate
field is not #f
, the
corresponding method of the object in the field is
invoked. This method receives the same arguments as the
original method, plus two extras. The extra arguments come
at the beginning of the argument list. The first is the
original object. The second is a procedure that calls the
super method, e.g., the method of the class that is
passed to the mixin, with the arguments that the procedure
receives.
The host interface has the names set-surrogate
,
get-surrogate
, and each of the
method-name
s in the original form.
The surrogate class has a single public method for each
method-name
in the surrogate
form. These
methods are invoked by classes constructed by the
mixin. Each has a corresponding method signature, as
described in the above paragraph. Each method just passes
its argument along to the super procedure it receives.
Note: if you derive a class from the surrogate class, do not
both call the super
argument and the super method
of the surrogate class itself. Only call one or the other,
since the default methods call the super
argument.
Finally, the interface contains all of the names specified
in surrogate's argument, plus on-enable-surrogate
and
on-disable-surrogate
. The class returned by
surrogate
implements this interface.