Joshua Bloch: A conversation about design

Effective Java's author discusses API design, reuse, and trust in Java environments

1 2 Page 2
Page 2 of 2

One problem with writing widely distributed source code is that people can go back and look at your code and say: Ah, but you didn't do it here. Generally speaking, I respond: Well, I learned a few things since I wrote that; now I know I have to do it. In this case, it's a question of how careful is your documentation? I'm probably not careful enough, and, yes, I think it's worth being careful.

Trust contracts

Venners: Should I trust that passed objects correctly implement their contract? Recently, I had to create a Set implementation that had a consistent serialized form between different virtual machines. I was writing a class I called ConsistentSet as a subclass of your nice AbstractSet, and I had a constructor that took a Set. In this constructor I simply wanted to copy the elements out of the passed Set into an array that formed the state of the new ConsistentSet. I put the elements in an array so that whenever the ConsistentSet was serialized in any virtual machine, the elements would get serialized in the same order.

As I wrote the code that pulled the elements out of the passed Set and copied them into the array, I wondered whether I should trust that this passed Set contains no duplicates? Because if I do, I'm relying on someone else to implement his contract correctly. And if the passed Set violates its contract by containing duplicate elements, it breaks my class. I'm also a Set and also supposed to contain no duplicates, so perhaps I should program defensively and check for duplicates in the passed Set as I copy its elements to my array. On the other hand, isn't a basic idea of object-oriented programming that you divide up responsibilities among different objects, and let each object perform its role as promised in its contract?

Bloch: I think you have no choice but to trust that objects implement their contracts. Once people start violating their contracts, the whole world falls apart. A simple example: Equal objects must have equal hash codes. If you created types for which this isn't true, hash tables and hash sets wouldn't work.

More generally, when objects stop obeying their contracts, objects around them start to break -- that's just the way it is. I can understand why it makes you nervous, but, yes, you do have to trust objects to implement their contracts. If you feel nervous, you can take a hint from the intelligence community and "trust but verify." The best way to do this is with assertions, because you don't pay for them when you turn them off. Use assertions to test that other objects are obeying their contracts, and, if your program starts acting strangely, enable assertions and you may well find out who is to blame.

Bill Venners has been writing software professionally for 14 years. Based in Silicon Valley, he provides software consulting and training services at Artima Software. He is the author of Inside the Java 2 Virtual Machine (McGraw-Hill Professional Publishing, 1999; ISBN: 0071350934 ) and creator of Artima.com, a resource for Java and Jini developers.

Learn more about this topic

Related:
1 2 Page 2
Page 2 of 2