Validate Arguments on the Client Side Whenever Reasonable

This establishes a connection, makes the query, and then releases the connection. Doing this enables the RMI runtime to perform distributed garbage collection and thus allows the server to perform cleanup actions e.g., releasing resources, persisting state at fairly appropriate times. However, in order for this to work, clients have to be good distributed citizens and relinquish their connections when they are done. Its possible to take this too far. If the client is going to make more method calls on the same server in a short period of time, its perfectly reasonable to keep a reference to the stub. If the client doesnt keep a reference to the active stub, the client will just have to contact the naming service again, and re-establish the same connection to the server.

9.4.2 Validate Arguments on the Client Side Whenever Reasonable

When we discussed how to design a remote interface in Chapt er 7 , one of the key questions was, Have we identified a reasonable set of distributed exceptions? There were two reasons for this. One was so that the client could behave correctly when the server experienced a failure. And the second was so that the client could validate method arguments as much as possible. It makes little sense for the client to invoke a remote method when it knows beforehand that such an invocation is already invalid. In our example, one major exception that the server could throw is NegativeArgumentException . However, the client is just as capable of checking this on its own without invoking a remote method. For example, when the client calls: public void makeWithdrawalMoney amount throws RemoteException, OverdraftException, NegativeAmountException; on an instance of AccountImpl , the client has no way of knowing whether the amount requested is an overdraft. However, it can certainly check to make sure the amount being withdrawn isnt a negative amount of money. In our implementation, weve defined a new subclass of Money , PositiveMoney , to handle this issue. PositiveMoney s constructor validates the cents values to make sure they are positive. And, since PositiveMoney extends Money , PositiveMoney will be a perfectly acceptable argument to the methods in our Account interface. Here is the constructor for PositiveMoney : public PositiveMoneyint cents throws Exception { supercents,; if _cents 0 { throw new ExceptionBad Value for Money; } return; } This isnt a very impressive code change, and it might seem like Im belaboring an obvious point. But the difference between the following two scenarios is enormous: • The user accidentally enters -120.00 as her withdrawal amount. She presses a button, waits 15 seconds and is told, You cant withdraw a negative amount. • The user accidentally enters -120.00 as her withdrawal amount. As soon as she presses a button, she is told, You cant withdraw a negative amount. The first application is perceived as slow and, consequently, not well designed; the second one is much faster. You can greatly improve perceived application performance by defining a rich set of exceptions and checking as many of them as possible on the client side. Do ATMs Really Do This? The example of checking to see whether a withdrawal amount is negative probably seems a little contrived. But look at your ATM machine the next time you make a withdrawal. There isnt even a minus key there. You are physically prevented from entering an incorrect amount. Moreover, if your bank is anything like mine, it has rules governing the amount you can withdraw. My bank has the following two rules: • The amount of money being withdrawn must be a multiple of 20. • No more than 300 can be withdrawn in any given day. These are enforced by two local checks and then three checks at the server. The local checks are: • The amount of money being withdrawn must be a multiple of 20. • The amount being withdrawn cannot be more than 300. The checks at the server are: • The amount of money being withdrawn must be a multiple of 20. • The amount being withdrawn cannot be more than 300. • The total withdrawn for the day cannot be more than 300. The first two checks are performed on the client side, for the reasons weve been discussing in the this chapter. Theyre also repeated on the server side, to prevent a badly written or malicious client from causing data integrity problems.

9.4.3 The Actual Client Application