scruffles.net subscribe
Tuesday, November 25, 2003

I was just reading the javadoc for Timestamp (which is a subclass of date). It has a disclaimer that's kind of entertaining:

"The Timestamp.equals(Object) method never returns true when passed a value of type java.util.Date because the nanos component of a date is unknown. As a result, the Timestamp.equals(Object) method is not symmetric with respect to the java.util.Date.equals(Object) method. Also, the hashcode method uses the underlying java.util.Data implementation and therefore does not include nanos in its computation. Due to the differences between the Timestamp class and the java.util.Date class mentioned above, it is recommended that code not view Timestamp values generically as an instance of java.util.Date. The inheritance relationship between Timestamp and java.util.Date really denotes implementation inheritance, and not type inheritance."

Translation:

"We really shouldn't have inherited from date, but we did anyway because favoring inheritance over composition has always worked for us in the past (isn't Swing swell, after all). We decided this was a good thing because - hey - we already wrote the code, and it's working. Besides, it's not really a problem if we document it, right?"

Labels:

Wednesday, November 19, 2003

Programmers I�ve known spend too much time learning �how� or �what� and not enough time learning why.

All programmers learn the three fundamental principles of object-oriented programming: inheritance, polymorphism and encapsulation. They learn rules about these concepts, such as �when possible, favor composition over inheritance�, the DRY principle: �don�t repeat yourself�, and �be sure to decouple view logic from business logic�. Programmers (being the intelligent math-educated people they are), memorize the rules and apply them whenever possible.

Here�s the problem. Most of these rules were not meant as absolutes. These are not like the rules of physics or geometry. These are more like the rules of grammar or art: �complementary colors provide contrast�; �photographers should use the rule of thirds when composing a shot� or �don�t wear white after labor day�.

You don�t become a better craftsman by knowing more rules than everyone else. You become better at your craft by understanding the rules, why they exist and what contexts they can be applied to.

A popular buzzword I�ve heard being abused lately is �decoupling�. Unlike with marketing buzzwords, the problem doesn�t seem to rest in a misunderstanding of the original definition. Programmers just don�t stop to consider why they are �decoupling� their code. It is true that in many cases programmers tend to write highly coupled code. Many programmers don�t appreciate encapsulation nearly as much as they should (at the class level or subsystem level). This has led to some great books such as �The Pragmatic Programmer� and �Effective Java� that re-teach the basic concepts of OOP. The authors repeat the rules we read every day and explain why they are important (again).

The average programmer will read an entire chapter on decoupling code and walk away with:
Decoupling = good
Coupling = bad
We see the results of this oversimplification every day: seven levels of indirection for a single Session Bean call? A property file that tells me how to find my property files directory? A programming language written in xml?

Lets get back to the concepts. Decoupling exists to improve encapsulation. Encapsulation exists to improve maintainability. Many times externalizing logic will improve maintainability. Many times you�re just making a big mess! Decoupling code for any reason other than maintainability is a waste of time.

I love The Pragmatic Programmer series by Hunt and Thomas and many other books that teach everyday concepts that everyone should understand. I wish some of these books would not only explain the benefits of their philosophies, but how to tell if you�re taking them too far. More importantly, however, I wish programmers would read these books, absorbing the concepts rather than just the rules.

Labels:

Thursday, November 6, 2003

EasyMock is a library to help create mock objects that aid in your unit testing. The framework uses dynamic proxies to implement a given interface and return the results you expect. It will also throw exceptions if an unexpected method is called (aiding in the creation of your mock objects) and count the number of times a method is called (which allows your unit test to test efficiency in a more measurable way than the usually pointless System.currentTimeMillis() method of testing).

The best advantage of using EasyMock, in my opinion, is to specify the results of your mock objects directly in your unit test. A simple test may call two or three methods on a class. EasyMock requires two lines to create the mock object:

MockControl control = MockControl.createControl(MyInterface.class);
MyInterface myMockObj = MockControl.getMock();

Each method you want to call needs to have its results defined:

myMockObj.getParm();
control.setReturnValue(�ABC�);

As you can see, setting up a simple method call requires only two lines of code. This allows you to create custom mock objects for different situations you may want to test without littering your source tree with mock objects (or filling your mock objects with logic that, itself, needs to be tested).

The limitation of EasyMock, of course is the dependency on interfaces. Although we should always be coding to interfaces, it rarely seems to work that way. Luckily, most need for Mock Objects will be limited to those classes that do (or should) have well defined interfaces (database access, file access, container classes such as doms, or classes with complicated logic).

Labels:

Bryan