My assignment mentions only a DB interface. Of that I created 2 derived interfaces, one for remote and the other for local use.
Classes implementing these interfaces provide the actual access to the database.
So there's a RemoteDB extending DB (though indirectly, I've directly extended DB to include some more functionality like returning an recordset instead of just an array of recordIds).
Neither is ever used directly. Instead I've 2 more wrappers, representing a remote or local connection, both of them extending an abstract base. A factory returns either one depending on whether a remote or local connection is requested. The RemoteConnection intercepts the RMI exceptions and wraps them in a generic DatabaseException which is the same that the LocalConnection does with the IOExceptions returned from the Data class.
So the entire network and standalone modes are transparent to all of the client application except the connect routine, the associated dialog to enter the connection details, and the factory which actually creates the connection object. All the factory knows is to either create a LocalConnection or an RMIConnection depending on one of the parameters used to call it.
Lots of code removed here of course, things like creating the local DataFile instance from a class retrieved using reflection for example.
There is a method declared in the Connection interface which returns the proxy in case of an RMIConnection, the actual Data instance in case of a LocalConnection.
The DecoratedDB and DecoratedDBRemote interfaces both extend the required DB interface, adding some convenience methods. The proxy wraps the Remote variant in order to rethrow RemoteExceptions as something else so as to present a common interface to the user irrespective of the actual connection type used.
Joined: Apr 27, 2006
Thanks for replying. Your design is good.
I am just curious.., as I understand, you have a connection factory to create either local or remote connection.Local connection uses local data access methods and remote connection uses remote data access methods(which are similar, but coded separately). The Connection class (returned by factory) still wraps both Local and Remote data access classes. If a data access enhancement is needed, it needs to be done in both the data access implementations.
Jeroen T Wenting
Joined: Apr 21, 2006
The Connection class is abstract, the local and remote versions derive from it. Only 2 places (at most) need to change to add another connection type, the factory and the Enum where those types are defined. There's really no way around that without defining the types outside the application (say in a properties file) and using reflection (which I do employ for some things).
So say I want to replace RMIConnection with SocketConnection, I just change the factory to return a SocketConnection (which I'd have to define) instead of an RMIConnection.
If I want to add another connection type larger changes of course are needed, that's unavoidable.