[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [computer-go] A design pattern for implementing the GTP
On 11 November 2004, "Chris Smith" wrote:
> The Problem and Requirements
>
> When designing my GTP layer I wanted it to be as simple as possible so that
> adding and removing commands wouldn't be troublesome. This ruled out using
> inheritance or a massive switch statements. The main thing I kept running
> into was how do you keep the list of known commands up to date at compile
> time without headache. If you needed to know the function names at compile
> time the best I could come up with was a hash table of command name /
> delegate (function pointer) pairs.
>
> However, in a moment of clarity I looked to reflection and found the answer.
> The communicator class has an instance of the computer-Go engine which it
> instantiates in its constructor and every function in the class is the
> implementation of a GTP command. So the 'clear_board' method is the
> implementation for the 'clear_board' GTP command.
> When a driver class is created it uses reflection to query all public
> methods in the Communicator class and then simply matches a command string
> with a method name and calls the function. By doing this you 1.) know every
> GTP function your Go program supports without having to update a list,
> database, hashtable, etc 2.) adding new or GTP commands is as simple as
> adding new functions and 3.) the implementation is very clean.
Caveat: I'm a lurker on the list and don't have a go/GTP program so
folks may choose to disregard my post. I do a good bit of java
development and thought I would offer another method for achieving the
same (well similar) ends.
For java programmers (I don't have any .NET experience but I expect it
might be similar), you don't even have to define all of your handlers
at compile time.
A java application is able to create instances of a class simply given
the name of the class.
Class gtpHandlerClass = Class.forName("clear_board");
Object handlerInstance = gtpHandlerClass.newInstance();
This invokes the zero-arg constructor. But the Class ref can be
used to obtain a specialized constructor and/or method lists if
that is desired.
The route I probably would take is to have the handler classes all
implement a common interface (similar to inheriting from an abstract
class for C++) where you could define common operational methods
(init, execute, etc.). So the above two lines would be followed by:
GTPCommandInterface gtpCommand = (GTPCommandInterface) handlerInstance;
gtpCommand.init(GTPInput input);
GTPOutput output = gtpCommand.execute();
In each of the implementation classes you could have all of the Object
methods like toString, etc. perform something reasonable (which eliminates
one of the drawbacks of using runtime-discovery of methods in a single
class that you mentioned).
The above code would need to be modified to implement error handling
(i.e. catch the ClassNotFoundException in cases where a command is
received but no implementation is available to handle it, and catch
the ClassCastException if the loaded handler doesn't actually implement
the required interface).
With this design, instead of having to make code-changes to your handler
class to implement new operations, you simply add a new java .class file
to your app's classpath and it will automatically be picked up at
runtime. This also would allow users of your package to substitute their
own handlers at runtime simply by changing the classpath order to point
to their own implementations if they wanted to override your default
behavior.
I also would probably implement some consist name-mangling scheme so
that the names of the java classes could conform to standard Java
naming practices rather than exactly matching the name of the GTP
command.
I'm not trying to suggest anything is wrong with your choice of design
but merely to offer another alternative. I apologize if this is out
of line for the list and I'll go back to lurking now :)
Daniel Hallmark
_______________________________________________
computer-go mailing list
computer-go@xxxxxxxxxxxxxxxxx
http://www.computer-go.org/mailman/listinfo/computer-go/