I found Andrew's book excellent for giving a grounding in what is required for the
SCJD certification and how to approach the daunting task
.
What I did differently is I used a 'thin client' approach for networking. I had a 3-tier architecture (gui, services and business layer).
My Services layer called a getServices() method dependant on run mode entered. In STANDALONE mode my getServices
method gets the Data singleton directly. For network clients when SERVER mode is entered I get a Data singleton which is
passed to RemoteServices for use in NETWORK-CLIENT mode. My ServicesImpl class which implements the Services
interface wraps IOExceptions in a ServicesException that is passed back to the gui. The ServicesImpl class is the only route
to the persistence layer from the gui and all exceptions that can be thrown are passed back from the 'service layer'.
My RemoteServicesImpl class implements the Remote interface and extends UnicastRemoteObject and because the
my Services Interface throws throws IOException there is no problem throwing a RemoteException here. This makes
exception handling very easy, and also makes the network layer very small. My Search() and Book() methods just
delegate to the Data singleton instance passed in SERVER mode when I run the application in NETWORK-CLIENT
mode (no run mode entered). When I call RemoteServices via RMI from Services for the client I cast the this back to Services.
Because of the 'thin client' approach and delegating to the Data class when entering SERVER mode, my network code
(the RemoteServicesImpl class) compiles to 3.57k.