The Artima Developer Community
Sponsored Link

Josh Bloch on Design
A Conversation with Effective Java Author, Josh Bloch
by Bill Venners
First Published in JavaWorld, January 4, 2002

<<  Page 5 of 19  >>

Advertisement

Trust versus Being Defensive

Bill Venners: Now I'd like to talk about trust. To what extent should I trust client programmers to do the right thing? You write in your book about making defensive copies of objects passed to and from methods. Defensive copying is an example of not trusting clients. Is there not a robustness versus performance tradeoff to defensive copying? Indeed, if you have arbitrarily large objects, could it be expensive to defensively copy every time?

Josh Bloch: Clearly there is a tradeoff. On the other hand, I don't believe in attacking performance problems too early. If it's not a problem, why bother attacking it? And there are other ways around the problem. One, of course, is immutability. If something can't be modified, then you don't have to copy it.

It is true you might opt in favor of performance rather than robustness and not copy something if you believe you are operating in a safe environment -- an environment where you know and trust your clients won't do the wrong thing. Certainly you'll find most C-based programs filled with comments saying: It is imperative that this method's client not modify the object after it is called, blah, blah, blah. Yes, you can successfully write code that way. Anyone who has programmed in C or C++ has done so. On the other hand, it's more difficult because you forget you cannot modify it, or you have aliasing. You don't modify it, but, oops, you've passed a reference to the same object to someone else who doesn't realize he shouldn't modify it.

All things being equal, it is easier to write correct code if you actually do the defensive copying or use immutability than if you depend on the programmer to do the right thing. So, unless you know that you have a performance need to allow this sort of error to happen, I think it's best to simply disallow it. Write the program, then see if it runs fast enough. If it doesn't, then decide whether you want to carefully relax those restrictions.

Generally speaking, you should not allow an ill-behaved client to ruin a server. You want to isolate failures from one module to the next, so that a failure in one module can't break a second module. It's a defense against intentional failures, as in hacking. And more commonly, it's a defense against sloppy programming or against bad documentation, where a user of some module doesn't understand his responsibilities in terms of modifying or not modifying some data object.

<<  Page 5 of 19  >>


Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2009 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us