Quote:
> : Does anyone know of a design pattern that describes a good implementation
> : of a way to properly enable and disable application functions based on
> : whatever criteria?
> Commands can often be grouped by some criteria. Then they can be enabled
> and disabled by group when this makes sense. These groups are often
> similar to, or related to, "modes" in a user interface. So however you
> handle modes of one kind or another, enabling a mode can be seen as also
> enabling the "visibility" of a group of commands. Finding a command can be
> seen as similar to finding a file in a search path.
The above is good advice, but you can take it even farther. Think about
the commands your system will accept at any given time and the
interpretation that the system will take of them at that time. This is
in some sense a definition of a "command" state. If, after a particular
command has been executed, something has changed, i.e., some command(s)
are now acceptable/unacceptable, or some commands are interpreted
differently, we can think of the system as being in a new state, where
the transition from the old state to the new state was caused by the
command previously entered.
What this means is that you can model command processing as a state
machine. At any time, all commands can be accepted by the machine, but
some will be carried out, some will be ignored and some will have errors
associated with them. In other words, each individual command is really
a polymorphic operation; the actual command which is invoked will be the
command in the object corresponding to the system's current state.
Let me clarify this:
suppose our system has three commands, x, y, z. In state 1, only x is
allowed (x is like a log in). State 2 happens after x is entered.
Here, y and z are valid, but x is ignored. If z is entered (like a log
out) we return to state 1.
Define a class command interpreter with part command and operation set
state.
We now define the superclass command to have 3 operations , x, y and z.
subclass command1 defines operation x to be the log on, and operation y
and z to do nothing.
subclass command2 defines operations y and z, but does nothing upon x.
In the command1.x operation the command interpreter is told to reset its
current state to 2. This causes the interpreter to instantiate an
object of type command2 and put it in part state.
in the command2.z operation the command interpreter is told to reset its
state to 1. This causes the interpreter to change part to an object of
class command1.
Every time the interpreter gets a command it dispatches it to the
appropriate operation in its current part. For example, if the part is
currently command1, an x will result in a log-in, if the part is
currently command2, x will be ignored.
An example of this is in the GoF pattern state. Try it, it's really
quite effective.