Friday, March 13, 2020

The Arbitrary Substitution Principle

There is, I believe, an important principle in software development for which I've found no discussion elsewhere. It's a principle that therefore deserves more exposure. It's the Arbitrary Substitution Principle (ASP). Cleopatra supposedly died from the bite of an asp [in fact, we're told by Wikipedia that that version of events is fake news].

But you too can be "bitten" by this particular asp if you're not careful.

There's a well-known problem in the study of binary search trees: Hibbard deletion. Here's some code that will do the job:

    private Node delete(Node x, Key key) {
        if (x == null) return null;
        int cmp = key.compareTo(x.key);
        if (cmp < 0) x.smaller = delete(x.smaller, key);
        else if (cmp > 0) x.larger = delete(x.larger, key);
        else {
            if (x.larger == null) return x.smaller;
            if (x.smaller == null) return x.larger;
            Node t = x;
            x = min(t.larger);
            x.larger = deleteMin(t.larger);
            x.smaller = t.smaller;
        }
        x.count = size(x.smaller) + size(x.larger) + 1;
        return x;
    }

Do you see anything wrong with this code? Look at the following three statements:

            x = min(t.larger);
            x.larger = deleteMin(t.larger);
            x.smaller = t.smaller;

We could instead have written:

            x = max(t.smaller);
            x.smaller = deleteMax(t.smaller);
            x.larger = t.larger;

Why did we substitute the first form in favor of the second form? No good reason. Note that, if there had been a good reason, we should have documented it in the form of a comment.

In fact, using the first code fragment leads to very poor performance--where operations on the BST become O(N^0.5) rather than O(log N). Choosing which to use randomly (or simply alternating) can ameliorate this problem significantly.

This sort of thing is a code smell no less serious than many other code smells.

OK, back to work!

Saturday, November 24, 2018

Euler's Identity

A little off the track of software but not entirely disconnected...

I've recently taken to mentioning Euler's Identity when we talk in Algorithms class about Euler and the Bridges of Königsberg.
I point out that it includes five of the most important numbers in mathematics: 0, 1, π, i (the square root of -1), and e, the base of natural logarithms (Euler's number); it also involves four of the most important operators: +, =, * and exponentiation.

The only numbers or operators that could be reasonably considered to complete the set would be the number 2 and division.

Have you ever wondered about the definition of π as the ratio of the circumference of a circle to its diameter? Why the diameter? Why not the radius? There are so many situations where we have to talk about 2π, for example the number of radians in a complete circle, or the "reduced" Planck constant (h/2π) as used in Schrödinger's equation).

So, what would be the effect of redefining π as the ratio of the circumference of a circle to its radius? To avoid the most appalling confusion, we would of course have to give it a different symbol. The greek letter tau has been proposed. Employing 𝝉 = 2π, the Euler identity would appear thus:
Now, we would have six numerical quantities and five operators. I have to admit though that it doesn't look quite so elegant this way.

For a more complete discussion of this use of 𝝉, please see Turn (geometry): section Tau Proposals.

OK, back to work!

Wednesday, July 18, 2018

The Sherlock Holmes Guide to Programming, Debugging and Performance Tuning

Back in 2009, I published on this very blog a set of programming "laws" which I modestly called "Hillyard's Laws of Programming." Here they are:
There has even been a fourth law, although that one is a little more nebulous even than the first three.

Recently, I have been working my way through the Sherlock Holmes canon, but listening to audio recordings rather than reading. I know the stories almost by heart but there is nothing like listening to someone else's interpretation to trigger little observations that may have escaped one on previous readings. I have thus realized that Sherlock Holmes has made many pronouncements to Watson, his amanuensis, that show that the art of detection and that of software development have so much in common that Holmes would have been a first-rate programmer if there had been computers in his day.

Of course, we must not forget that Holmes, despite his familiarity, was in fact fictional--the creation of Sir Arthur Conan Doyle. Doyle was a strange man. Despite being scientifically trained, he was nevertheless a believer in all sorts of hocus-pocus. But the statements which he has Holmes make are prescient when considered in the realm of programming.

There are of course many sub-disciplines involved in software engineering, development, coding, whatever you want to call it, including (but not limited to):
  • programming (relating use cases to a particular design);
  • debugging;
  • performance tuning.
Of these, the greatest degree of mystery pertains to debugging and, perhaps to a lesser extent, performance tuning. It is to these activities that most of these statements relate most appropriately.

From The Sign of Four, one of the early novellas, he writes:
"Eliminate all other factors, and the one which remains must be the truth."
Or, similarly, look first at the following statement from the The Adventure of the Beryl Coronet:
"It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth."
I alluded to this in my "First Law." If you have positively eliminated a fragment of code from your pool of suspicion, then the problem must be in some other part of the program, even if that seems highly unlikely. I have personally spent hours looking at the same bit of code, trying to find a flaw in it, only to realize later that I was looking in the wrong place! 

It is all too easy to assume that some part of the code (which was "working before" or which has been tested by someone else, etc.) is perfect. Sherlock Holmes puts it well in The Adventure of the Reigate Squires: 
“Now, I make a point of never having any prejudices, and of following docilely wherever fact may lead me, …”
This observation applies manifestly to performance tuning also. It is so easy to make assumptions, such as "if I cache this, then the performance must improve." Never do any such thing without testing the result.

When faced with a plethora of possibly conflicting results, it is important to know which you should trust the most. For example, you cannot trust the order in which buffered I/O occurs. If you need to be sure of the order, then you should use logs or unbuffered I/O. 

Sherlock Holmes summed it up thus, again from the same story:
“It is of the highest importance in the art of detection to be able to recognize, out of a number of facts, which are incidental and which vital. Otherwise your energy and attention must be dissipated instead of being concentrated.”
So, to employ our example above, the order of buffered output is incidental whereas the order in logs is (usually) vital.

My second "law" has to do with the situation you sometimes find yourself in where there are two seemingly independent problems with your code. Let's say you are concentrating on problem A, which is proving challenging but so far intractable, while you are aware of an apparently minor problem B for which you think you have a simple solution. It's tempting to concentrate your efforts on the more interesting problem (A). But you would be well advised to take a slight detour and fix problem B. You never know: that fix might also be the solution to problem A (it's happened to me many times).

Holmes understood this also, as evidenced by this comment from The Adventure of the Musgrave Ritual: 
“‘At least,' said [Holmes], 'it gives us another mystery, and one which is even more interesting than the first. It may be that the solution of the one may prove to be the solution of the other.”
The third "law" relates to the practice of peer programming. I can't count the number of times I've asked someone for help and then, midway through explaining the background of the problem, I've realized my own error. Holmes was aware of this phenomenon too, for he states in The Adventure of the Blue Carbuncle: 
“Not at all. I am glad to have a friend with whom I can discuss my results.”
And, even more explicitly, he discusses it in The Adventure of Silver Blaze:
“At least I have got a grip of the essential facts of the case. I shall enumerate them to you, for nothing clears up a case so much as stating it to another person, and I can hardly expect your co-operation if I do not show you the position from which we start.”
A certain amount of imagination is also extremely helpful when trying to solve a problem. If you imagine a particular scenario, it may follow that the currently mystifying behavior of your code comes to be a natural outcome of your imagined situation. Again from Silver Blaze (incidentally, one of the very best stories):
”See the value of imagination," said Holmes. "It is the one quality which Gregory lacks. We imagined what might have happened, acted upon the supposition, and find ourselves justified. Let us proceed."
Sometimes a clue comes to you not from observed behavior but from expected behavior that you do not observe. Many's the time I have instrumented some method with a log message or unbuffered print statement only to find that I get no output whatsoever. This usually is enough to tell me that, despite my expectations, the method was never actually called. One of the most famous exchanges of Sherlock Holmes covers this point (again from Silver Blaze):
[Inspector Gregory] “Is there any other point to which you would wish to draw my attention?” 
“To the curious incident of the dog in the night time.” 
“The dog did nothing in the night-time.” 
"That was the curious incident,” remarked Sherlock Holmes.
Let us now return to the second passage quoted above, having to do with casting any prior prejudices aside. I would venture to suggest that this is perhaps the most important guideline that Holmes give us: to carefully gather as much of our evidence as possible before forming a theory. He sums this attitude up in the very first of the Sherlock Holmes stories published in the Strand Magazine--A Scandal in Bohemia:
“This is indeed a mystery,” I [Watson] remarked [to Holmes]. “What do you imagine that it means?” 
“I have no data yet. It is a capital mistake to theorise before one has data. Insensibly one begins to twist facts to suit theories, instead of theories to suit facts.”
His basic theme is similar in the following statement from The Sign of Four:


“No, no: I never guess. It is a shocking habit,—destructive to the logical faculty.” 
I hope that these utterances of Sherlock Holmes will help you take the proper course of action when presented with a problem in programming, debugging or performance tuning. Clearly, my remarks are intended to apply to any program language or system, not just Java.

OK, back to work!

Updated with quotations from The Sign of Four, Mar 12 2019

Friday, January 19, 2018

Things that Java got wrong - part 4

This is perhaps rather less serious than some of my other nitpicks regarding Java. This relates to the admonishment by the Java collections classes that they only work correctly if the hashCode and equals methods of an object are consistent.

If that is a requirement--and I think we'd all agree that it is--then why allow it to be otherwise? Require that those two methods are delegated to an inner class that forces them to be consistent.

This is the kind of thing I have in mind...

The first component is a class called Equable which implements both equals and hashCode. There is a constructor which takes an Iterable of objects, which correspond to the fields of a user type. Here's a link to the source on github.

BaseEquable is an abstract class which can be extended by a user type and which defines both equals and hashCode in terms of an abstract method getEquable which returns, for a sub-type, an instance of Equable. Source link.

A user type which extends BaseEquable simply has to implement getEquable something like this (where, in this example, there are two fields: x and y):

@Override
public Equable getEquable() {
Collection<Object> elements = new ArrayList<>();
elements.add(x);
elements.add(y);
return new Equable(elements);
}

Now, because the actual work of equals and hashCode is delegated to methods which enforce consistency, there is no danger of those two methods being inconsistent. I've also demonstrated (in the same repository of github) that it's easy to extend to including a consistent version of compareTo also.

OK, back to work!

Wednesday, February 11, 2015

Things that Java got wrong, part 3

Last time in this series (Things that Java got wrong, part 2), I talked about interfaces and the lack of an ability to include default method bodies. Happily, this major oversight has been fixed in Java 1.8.

But now I want to rail against another aspect of interfaces and abstract types (or rather their usage) that I think is by far the worst thing that the Java designers ever messed up. The "Number" type.

First, let's look at three simple reasons why java.lang.Number is so bad.
  • it should be an interface -- or rather several interfaces -- but instead it is an abstract type;
  • if it is going to be an abstract type, then at least let's have it implement Comparable<Number> --- but it doesn't; all of its sub-classes, say X, implement Comparable<X> but that's not the same thing at all: if you need a generic type that implements Number and Comparable, it can't be done without creating your own type!
  • it doesn't even have a method to let you find out if the type is integral or real (forget about complex) -- you have a Number, you can check if it implements Integer, Long, etc. but if somebody creates a new sub-class of Number that happens to be integral, you won't catch it.
I ran into all of these problems recently while working on a new open-source framework for dealing with fuzzy objects (i.e. objects with uncertainty) and they caused me some big headaches. You can find the project at FuzzyJ.

Let's think about how we would go about defining an interface (or interfaces) to represent numbers. Sounds pretty straightforward, right? But it isn't quite that simple. There's a world of difference between the integers, where the successor or predecessor operators make perfect sense, and the real numbers where those operators don't make much sense -- while operators such as round are useful. And then there are complex numbers, rational numbers, irrational numbers, etc. etc. In other words, different types of numbers require different methods. In fact, to put it another way by inverting the question, the operators essentially define the number classes. Is there a fundamental set of operators that would apply to all numbers? There really isn't. But a reasonable set that works with most types of number is this: addition, multiplication, negation, perhaps some others, including compare with.

But already we run into problems. If the set of numbers you're modeling is the positive integers, then negation makes no sense.

So, let's start out with something like this:

public interface Numeric extends Comparable<numeric> {
 Numeric add(Numeric other);
 Numeric multiply(Numeric other);
}
This will work for the positive integers and most other classes. If we want to extend the class to all integers, then we can define the following:
public interface Integral extends Numeric {
 Numeric negate(Numeric other);
}

So far so good. We can now define an IntegralBase class based on the int primitive:

public class IntegralBase implements Integral {

 private int value;

 public IntegralBase(int value) {
  super();
  this.value = value;
 }

 @Override
 public Numeric add(Numeric other) {
  if (other instanceof IntegralBase)
   return new IntegralBase(this.value+((IntegralBase) other).value);
  throw new RuntimeException("cannot add non-IntegralBase object");
 }

 @Override
 public Numeric multiply(Numeric other) {
  if (other instanceof IntegralBase)
   return new IntegralBase(this.value*((IntegralBase) other).value);
  throw new RuntimeException("cannot multiply non-IntegralBase object");
 }

 @Override
 public int compareTo(Numeric other) {
  if (other instanceof IntegralBase)
   return Integer.compare(this.value, ((IntegralBase) other).value);
  throw new RuntimeException("cannot add non-IntegralBase object");
 }

 @Override
 public Integral negate(Integral other) {
  return new IntegralBase(-this.value);
 }
}
But we're already beginning to get into difficulties. We don't have anything good to do if we try to add (multiply, or compare) an object which is not Integral (or, more specifically, an IntegralBase). What if the "int" primitive isn't sufficient for our purposes and we need a BigInteger? We could define a BigIntegral class just like the one above. Or we could make Integral generic, except of course that "int" cannot be a generic type because it's a primitive.

But even this is better than the setup that the Java designers gave us. What we have in Java is an abstract type (not an interface) called Number.

public abstract class Number implements java.io.Serializable {

    public abstract int intValue();

    public abstract double doubleValue();

    // etc. etc.
}
That's basically all there is apart from longValue, floatValue, etc. There's no good way to find out if the object we are dealing with is a whole number (operable with one set of operations) or a real number (operable with another set, with some overlap).

The designers of the math3 package from Apache "commons" have helped somewhat. They do bring in a little mathematics withe the Field and FieldElement interfaces. And they provide a type for rational numbers in BigFraction.

But in my humble opinion, Java, while it is admittedly a general-purpose language, could have done so much better right from the start.

OK, back to work.

Monday, November 17, 2014

TiVo

I love TiVo, that's to say I love digital video recorders. I've been letting TiVo simplify my life -- and avoid commercials -- for 13 years now.

Nevertheless, I'm going to use the TiVo user interface as an example of how not to write user interfaces. It seems that they cobbled together something pretty basic when they got started in 1999 and they haven't improved it since. There have been a few minor tweaks and/or name changes but nothing substantial. I don't have the Roamio -- maybe the user interface there is different [see postscript] -- but the classic UI on my "series 3" is simply a bad design that has never been fixed.

According to Wikipedia, there are seven principles of user interface design. While the TiVo design does an adequate job with six of the seven principles, I believe it falls quite short in the seventh:
  • Conformity with user expectations: the dialogue conforms with user expectations when it is consistent and corresponds to the user characteristics, such as task knowledge, education, experience, and to commonly accepted conventions.
What this says in other words is that the UI should operate on the same model of the world (or, more specifically, the relevant subset of the world) as does the user. That makes it user-centric, rather than information-centric, system-centric or whatever. It is the job of the UI (not the user) to translate between the user's model of the world and the system's internal model.

Let me start with the simplest and most fundamental error: when you are, say, watching live TV and you go up to the top-level menu, you would naturally expect that "live TV" would be the current selection. But no, "Now Playing List" is the new selection. That means that if you inadvertently clicked up to the menu and then pressed "Select" you would expect to be back watching live TV -- but you aren't. That breaks perhaps the #1 rule of user interface design: the principle of least surprise. Or, to put it in terms of the above definition, the UI is supposed to be conform to user expectations and be consistent.

Another major mismatch between the TiVo UI model and the way viewers think: channels. Back in the day when there were just a few channels available, essentially one per network, the concept of a channel meant something. You just "knew" which channel a program would be on and it didn't make any sense for it to be on a different channel. But that situation was long gone, here in the USA at least, when TiVo was introduced so it has never made any sense. The viewer simply doesn't care which channel something is on. And, truth be told, neither does TiVo. Yet the user is required, when setting up a Season Pass, for example, to specify the channel. The Season Pass largely ignores this information because it actually lists all of the upcoming episodes, regardless of channel. The user does distinguish between first-run and repeats. And TiVo asks about that. But when listing episodes, it doesn't make any distinction. Consistency!

Another issue that is a fundamental breach of UI design (but strangely is not mentioned in the Wiki article) is that the controller should always be "live." That is to say, there should never be an operation that the user can initiate that he can't cancel or switch to some other operation. Frequently, TiVo goes into a funk while it is reacting to a user command -- and the user is helpless until the action finishes. And there isn't even an indication of how long the action is likely to take.

But my biggest complaint of all is that TiVo has not changed the model to accommodate high-definition TV. Although HDTV was, in theory at least, around in 1999 when TiVo was launched, it didn't become mainstream until the mid-2000s. The PBS HD channel began operations in 2004, for example. Should TiVo have anticipated HD? Of course they should, but it probably would have been acceptable for them to remodel the UI after their first few years of operation. Note that I am talking about the UI here. At some point (around 2005?) new TiVos did support recording and playing HD programs. But the UI continues in blissful ignorance of this rather important concept. For example, when setting up a Season Pass, you cannot specify that you do (or do not) want to record in HD. You can try to persuade the TiVo by specifying you want to record from an HD-only channel (in order to do this, however, you have to delete the old season pass and reprogram it -- unbelievable). But even then, the only way you can insist that a program be recorded in HD is to tell TiVo that you don't receive the corresponding non-HD channel(s). Bizarre in the extreme.

There are many other issues that I have with the TiVo UI. Things that they certainly ought to have fixed in 13 years! But I've covered the main points.

The conclusion? When you're designing a UI, don't think about the way your system works, or how the information is stored in your internal storage. Think about the way the user will want to interact with the system, how he or she will "think" about what they are doing. Model that instead and make all of the interactions consistent with that model. Yes, that's work. But isn't that what your paid for?

OK, back to work!

Postscript: I drafted this on 10/31 and the very next day my TiVo expired (the fan stopped working). No, I don't think it was a conspiracy between Google and TiVo. The TiVo people were quite helpful in getting me an upgrade to the Roamio. It was a significant operation to get it working, requiring collaboration with three different and not entirely cooperative entities: TiVo, Comcast and me. And my old expander disc, while "compatible" with the new model, is completely unreadable. So, basically, I lost everything that I had previously recorded. This seems the height of poor system design. Why on earth would they consider the internal disc and the external disc to be one single volume?

But the look and feel has improved enormously. The TiVo menus are now in HD and they have fixed quite a few of the problems I mentioned above. How is it, though, that those improvements were not available to the old Series 3? There are still breaches of the principle of least surprise. For instance, if you set up a season pass now and choose "new" only, the default channel chosen will, it seems, most likely be a channel that only shows re-runs. You can change it if you happen to notice, but TiVo will not warn you that the season pass will do nothing.

Wednesday, August 27, 2014

Exception handling -- part 2

I last previously talked about exception handling in a blog a couple of years ago: Exception Handling. That was a fairly short blog which attempted to cure some of the more nefarious problems in exception handling which I sometimes see in code. Following these recommendations (nothing that isn't already very obvious) will result in "OK" code.

Now, I want to write up some more advanced guidelines such that following them will, in my humble opinion of course, improve "OK" code to "good" code.

I'm going to refer to the excellent tutorial on Java Exceptions as I continue. You should definitely read and inwardly digest that material. I particularly recommend the section Unchecked Exceptions -- the Controversy.

In the throwing and handling of exceptions, it seems to me that context is everything. This is why we sometimes wrap one exception in another -- because it allows us to add context. But there's another reason to wrap an exception. Here's a common situation:

import java.security.GeneralSecurityException;
import java.sql.Blob;
import java.sql.SQLException;

import javax.crypto.Cipher;

import org.apache.derby.iapi.jdbc.BrokeredConnection;
import org.apache.derby.iapi.jdbc.BrokeredConnectionControl;

public class MyConnection extends BrokeredConnection {

 public MyConnection(final BrokeredConnectionControl bcc, final Cipher cipher) throws SQLException {
  super(bcc);
  this.cipher = cipher;
 }

 public Blob createBlob() throws SQLException {
  return new EncryptedBlob(this.cipher) {

   public byte[] getBytes(final long pos, final int length) throws SQLException {
    final byte[] data = new byte[length];
    // Fill in the actual data from somewhere
    try {
 return this.cipher.doFinal(data, (int) pos, 0);
    } catch (final GeneralSecurityException e) {
 throw new SQLException("crypto problem with cipher "+this.cipher
   + ", length: " + length, e);
    }
   }
  };
 }

 Cipher cipher;
}

public abstract class EncryptedBlob implements Blob {

 protected Cipher cipher;

 /**
  * @param cipher the cipher to use for encryption/decryption
  * 
  */
 public EncryptedBlob(Cipher cipher) {
  super();
  this.cipher = cipher;
 }

 public long length() throws SQLException {
  return 0;
 }

        // etc. etc.
}

Here, we are extending the (Apache) Derby Connection implementation to allow for encryption/decryption of blobs. The details aren't important. But note the signature of the getBytes() method in the blob implementation. It throws a SQLException. But when we try to perform encryption, we are going to have to deal with a GeneralSecurityException. We have no choice about whether to catch or specify: we must catch it. We could eat the exception but that wouldn't be very good (see previous blog)! But since we have the ability to throw a SQLException, we will do just that: wrap the caught exception inside a SQLException. This of course also gives us the opportunity to provide some context: in this case, we don't want to pass back actual data which would be potentially insecure but, since the cipher details and the length of the byte array are quite likely to be relevant, we add those in.

What happens when we are implementing a method that doesn't throw an exception? An example of this is in the ActionListener interface, the actionPerformed(ActionEvent e) method.

 new ActionListener() {
   
  public void actionPerformed(ActionEvent e) {
   // call method that throws a checked exception  
   }
  };

The problem here is that we can't specify the exception in the method signature and we can't wrap the exception in a checked exception. We have to either handle it somehow, or throw it as a RuntimeException. That's OK. It essentially will therefore treat whatever exception is thrown as a programming (logic) error. In other words, by the time the exception bubbles up to a potential handler, we really won't be able to handle it unless we specifically catch RuntimeExceptions. And then we would have to look to see if the cause was possible to be handled. This doesn't really make good sense.

However, I should also note that, as beauty is in the eye of the beholder, so too an exception is a programming (logic) error according to the programmer. Suppose you parsing a String as a Number. If the String was created by code, then the exception is probably justified as a RuntimeException (which it is: NumberFormatException extends RuntimeException). But what if this String was read from a file or the user just typed it in. That's not a logic error. Now, we want it to be a checked exception because we must handle it somehow. So, I'm not sure that the line between checked and unchecked exceptions is quite as clear as the tutorial suggests. In this particular case, for example, the Java designers seem to have got it wrong.

If you find yourself wrapping an exception of type A in a new exception of type A, then you almost certainly shouldn't be doing it. You wrap for necessity (as above) or context. Unless there's significant context to add, you should probably leave the exception alone and let it be passed up the stack.

Now, I want to talk about handling exceptions by logging. Let's say you decide to catch an exception rather than passing it up as is. You must handle the exception by one of the following:
  • performing some other logic based on the information that an exception was thrown [for example converting a String to a Number: you first call Integer.parse(x) and if that throws a NumberFormatException  you instead try Double.parse(x)].
  • wrapping it in a new exception (as described above).
  • logging it.
In the last case, you are asserting that it's OK to continue. Meanwhile, for the purpose of improving the product you have kept a record of the incident and, if it was caused by a bug you have, in the logs, the stack trace to help in debugging.

But you shouldn't do more than one of these things. Think of it this way: there shouldn't be more than one reference to the exception. We should never, for example, find an exception has been logged twice. In the following code, the try/catch in doMain() is completely unnecessary. And it results in two copies of the exception going forward. Bad practice.
public class X {

 public void doSomethingUseful() throws Exception {
  throw new Exception("problem");
 }

 protected void doMain() throws Exception {
  try {
   doSomethingUseful();
  } catch (final Exception e) {
   logger.log(Level.WARNING, "something bad", e);
   throw new Exception("wrapped", e);
  }
 }

 private static Logger logger = Logger.getLogger(X.class.getName());

 public static void main(final String[] args) {
  final X x = new X();
  try {
   x.doMain();
  } catch (final Exception e) {
   e.printStackTrace();
  }
 }
}

If you are writing UI code and an exception bubbles up from below, then it makes sense to do the following:
  1. log it; and
  2. if appropriate, tell the user what went wrong (in terms the user will understand, which is generally not the way exceptions are created) and what he/she can do about it.
Finally, I want to strongly suggest the following rules (which I will not attempt to justify):

  • There should be no more than one try/catch/finally block in any one method. Parallel to this rule is that there should be no more than one loop clause in a method (and ideally only one if construct).
  • Don't bother to catch any exceptions in a private method unless you are going to do something really useful with it.
  • As much as possible (Java 1.7 is good here) bunch the catch clauses together.
  • Be careful only to catch the types of exception that you really want to handle (and can handle) -- don't for example specify Exception in a catch clause because you will end up catching RuntimeExceptions and you won't know if it's safe to proceed. It's OK to catch a superclass (e.g. GeneralSecurityException) but Exception is just too generic.
  • User try-with-resource when appropriate (Java 1.7).
OK, back to work!

Friday, April 18, 2014

Reactive Programming

LinkedIn invited me to write a blog on the site (I don't know if this is a special privilege or the ask everyone) but I wanted to write about Reactive Programming. I have a friend who is looking for work and has been around the block in the software industry for a long time (we're the same age). So, I was able to use his situation as the seed for the idea.

If you'd like to read it, here it is.

OK, back to work!

Friday, October 19, 2012

More ways to try to maximize quality

Yesterday we looked at unit testing, especially test-driven development.  I'm going to add one more type of test here: a test for a private method (or any method which is otherwise out of scope).

Take a look at these two methods in the test class:
 @Test
 public void getTotal_A$() throws Exception {
  final Randomizer target = new Randomizer(getRandom());
  assertEquals(0, getTotal(target));
  target.setBands(1, 2, 3, 4);
  assertEquals(10, getTotal(target));
 }

 private int getTotal(final Randomizer target) throws Exception {
  Object total = TestUtilities.invokeInstanceMethod(target, "getTotal", new Class[] {}, new Object[] {}); //$NON-NLS-1$
  assertTrue(total instanceof Integer);
  return ((Integer) total).intValue();
 }


Most of the time, we can probably skip testing private methods.  But there are times when the private method contains some especially tricky logic, which is then further complicated by its caller(s) and we want to isolate the test to focus on precisely the private method.  I use a utility method which is in a class called TestUtilities which I put in the test directory along with the unit test classes.  The particular method used here is simple enough - I'll just show it in-lined (although the class actually has a number of methods with convenient signatures and is rather more elegant).
 public static Object invokeInstanceMethod(final Object instance, final String methodName, final Class[] paramClasses,
   final Object[] paramObjects) throws Exception {
  final Method method = instance.getClass().getDeclaredMethod(methodName, paramClasses);
  method.setAccessible(true);
  return method.invoke(instance, paramObjects);


Now let's take a look at some tools to try to improve code quality.  In a previous blog, I extolled the virtues of cleaning up code (using the cleanup tool in Eclipse, for example) before commiting to source control. However, perhaps I didn't sufficiently emphasize that it is not just formatting that is significant, but code cleanup. So, let's assume that our code has been cleaned up by Eclipse (or whatever) and compiles and passes all of its unit tests.

First, I want to take a look at the dreaded NullPointerException.  You definitely want to turn on the Java compiler warning which warns that this is possible ("Null pointer access" under "Potential programming problems"). This can find some possible problems, but it's not nearly as good in Eclipse Indigo as it is in Juno (Eclipse version 4).  Juno has annotations to allow you to explicitly set the expected behavior of references.  There are also the
javax.validation.constraints annotations like @NotNull though I'm not sure how useful these really in practice.  Until we can adopt the Juno annotations, we can try to avoid using variables (and initializing them to null) when we should be using constants.  And, unless it is explicitly covered as a potential and valid return value, methods should never return null.  If null is an invalid response it is better to throw an exception.  Assertions can also be used (by specying the -ea compiler option), but these have always seemed a crude way of doing things.  Annotations are much more appropriate.

I like another Eclipse plugin called FindBugs.  This will run on selected code (whole projects if you like) and come up with some potential bugs.  In this case, it takes mild exception to the test class, generating 7 warnings like the following:
RandomizerTest.java:54 Random object created and used only once in RandomizerTest.nextBoolean_A$()
This is not particularly helpful because we knew that already - this is the test class, remember?  Strangely, it doesn't seem to care that there are about a dozen potential null-pointer exceptions.  Occasionally, it will complain about something that you want to keep as is.  There is generally an annotation that you can specify which will tell it not to "bug" you about that in the future (similar to the annotations that you can use to switch off specific compiler warnings).
Then finally, when you've fixed all of the warnings that the compiler gives, and all of the bugs that FindBugs finds, and dealt with any null pointer issues, it's time to look for code "smells".  This is my favorite part.  Most of the time I just look and get that feeling that something's, well, fishy.  But you can do it more scientifically.  The tool I'm most familiar with, another Eclipse plugin, is called JDeodorant.

It has a strange user interface that I really dislike but it does work and can detect four "flavors" of code smell: God class, Long method, Type checking and Feature envy. Even though my example is quite short and reasonably well programmed, JDeodorant does find a few odors and with recommendations for fixing, for example under God class, it does suggest a refactoring and similarly under Long method.  It will offer to refactor the code for you.  This is all well and good if the changes are just to one file because you can revert to a previous version if you like.  But be careful if several files will be refactored, as feature envy often suggests.  I would only use that after checking everything else into source control.

Going beyond the level of source code, of course there are profiles and other performance enhancing tools but these are beyond the scope of this article.  There is one other tool that I like to help maintain architectural integrity of packages (packages are perhaps the least well thought-out aspect of Java).  It is called SonarJ and can really help with getting your house in order, architecturally speaking, by detecting cycles (A calls B, B calls C, C calls A, etc.).  It will recommend how to break these cycles by introducing interfaces.  Even a relatively simple package (or set of packages) can be surprisingly complex - and you really need a good tool to keep things in order.
OK, back to work!

Thursday, October 18, 2012

Test-driven development

To my mind, the most important software develoment tool, next to the compiler, I suppose, is a unit test framework.  I wrote one of these back in 1985 and I regret that I couldn't persuade the company to develop it further, perhaps even replacing our actual product.  But back in those days, the other tools just weren't ready for unit testing -- everything took far too long and we didn't have anything like continuous integration or even an IDE.  There was a powerful Q/A lobby which saw unit testing as trying to put them out of work!

Fast forward to 2012 and not only do we have unit testing, we have mockers and test-code generators.  I will admit right now that I am not an expert (barely a novice) in the realm of mocking.  It may be that some of what I am about to describe could be done better a different way.  No matter, onward.

I like to use a little tool called JUnitHelper which is an Eclipse plugin.  Now, it certainly has its quirks and idiosyncracies.  But it does do a basic first cut at a set of methods that "cover" all of the (non-private) methods declared in a source file.  And it makes it easy to hop back and forth between test class and test target class (Alt 9 and Alt 8).  When you enter Alt 9 (you can of course do it via menu commands too) it will add any test methods that have become necessary since you last did an Alt 9.  If there is no test class at all (defined by adding "Test" to type name), it will create one for you.  There are options so you can vary (a little) the various things that it does for you.

So here's what it produces for the Randomizer class that we talked about in the last blog (assuming we have it set to generate JUnit 4 tests):
package phasmid;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;

import org.apache.commons.math3.random.RandomGenerator;
import org.junit.Test;

public class RandomizerTest {

 @Test
 public void type() throws Exception {
  // TODO auto-generated by JUnit Helper.
  assertThat(Randomizer.class, notNullValue());
 }

 @Test
 public void instantiation() throws Exception {
  // TODO auto-generated by JUnit Helper.
  RandomGenerator random = null;
  Randomizer target = new Randomizer(random);
  assertThat(target, notNullValue());
 }

 @Test
 public void nextBoolean_A$() throws Exception {
  // TODO auto-generated by JUnit Helper.
  RandomGenerator random = null;
  Randomizer target = new Randomizer(random);
  boolean actual = target.nextBoolean();
  boolean expected = false;
  assertThat(actual, is(equalTo(expected)));
 }
etc. etc.....
I'm not in love with having those // TODO lines added but I suppose that's their way of advertising.  I'd prefer it to use more readable assertions such as:
  assertNotNull(Randomizer.class);

  instead of
  assertThat(Randomizer.class, notNullValue());


or 
  boolean actual = target.nextBoolean();
  assertFalse(actual);

  instead of


  boolean actual = target.nextBoolean();
  boolean expected = false;
  assertThat(actual, is(equalTo(expected)));

  or, better yet,
  assertFalse(target.nextBoolean());


But these details aren't too significant.  Another possible improvement might be to create a @Before setup method which reinitializes a field to a given state before each test.  Then you would, typically, only need to have one initializer for each field, instead of an initializer per field per method.  But, again, small potatoes.

I will actually create that method just so that the code is a little more readable.

So, now let's get to some real work.  We want to be able to set an array of relative frequencies for the various "bands" of the wheel of fortune.  So we create a test method to set those bands.  We will also create a test method to get the next index.  We will try to name these tests according to the scheme specified in the options for JUnitHelper (but if we don't, it won't be the end of the world, we will just ultimately end up with two test methods for one target method).

This is how the start of our test class looks now:
 private RandomGenerator random;

 @Before
 public void setup() {
  setRandom(new JDKRandomGenerator());
  getRandom().setSeed(0);
 }
 
 @Test
 public void setBands_A$() {
  Randomizer target = new Randomizer(getRandom());
  target.setBands(new int[]{1,2});
 }

 @Test
 public void nextIndex_A$() {
  Randomizer target = new Randomizer(getRandom());
  int actual = target.nextIndex();
 }

 @Test
 public void type() throws Exception {
  assertNotNull(Randomizer.class);
 }


Errors appear for setBands(...) and nextIndex() because these methods don't yet exist (so you also don't get any auto-complete when typing those names, obviously).

So, we opt for the appropriate quick fix: create the methods in the target class. But before fleshing these new method bodies out, let's actually define the behavior that we want right now.

We want the default behavior (if no bands are set) of nextIndex() to match what nextInt() would return if its parameter was Integer.MAX_VALUE.  So, let's code that in our test method for nextIndex.  But we will also add logic to test the invocation of setBands() and a subsequent call to getIndex() [actually, we will make many such calls].

We also check that the delegated methods behave as expected.

This is what (the start of) our test class looks like now:
 private static final int SEED = 0;

 private RandomGenerator random;

 @Before
 public void setup() {
  setRandom(new JDKRandomGenerator());
  getRandom().setSeed(SEED);
 }

 @Test
 public void setBands_A$() {
  Randomizer target = new Randomizer(getRandom());
  target.setBands(new int[] { 1, 2 });
  int[] counts = new int[] { 0, 0};
  final int n = 100000;
  for (int i = 0; i < n; i++) {
   int nextIndex = target.nextIndex();
   assertTrue(nextIndex == 1 || nextIndex == 0);
   counts[nextIndex]++;
  }
  assertTrue(counts[0] + counts[1] == n);
  assertTrue(Math.abs(counts[1] - 2 * counts[0]) < 500);
 }

 @Test
 public void nextIndex_A$() {
  Randomizer target = new Randomizer(getRandom());
  int actual = target.nextIndex();
  getRandom().setSeed(SEED);
  int nextInt = target.nextInt(Integer.MAX_VALUE);
  assertEquals(nextInt, actual);
 }

 @Test
 public void type() throws Exception {
  assertNotNull(Randomizer.class);
 }

 @Test
 public void instantiation() throws Exception {
  Randomizer target = new Randomizer(getRandom());
  assertThat(target, notNullValue());
 }

 @Test
 public void nextBoolean_A$() throws Exception {
  Randomizer target = new Randomizer(getRandom());
  final boolean actual = target.nextBoolean();
  boolean expected = new Random(SEED).nextBoolean();
  assertEquals(expected, actual);
 }

 @Test
 public void nextBytes_A$byteArray() throws Exception {
  Randomizer target = new Randomizer(getRandom());
  byte[] actual = new byte[] {};
  target.nextBytes(actual);
  byte[] expected = new byte[] {};
  new Random(SEED).nextBytes(expected);
  assertTrue(Arrays.equals(expected, actual));
 }
Notice that we've completely define the desired behavior of the setBands() and nextIndex() methods but we still haven't actually coded the case where there are bands set.  Not surprisingly, the unit test runs excatp that there is an assertion error in the setBands_A$() method.

Wouldn't it be nice if we could get that written for us.  Well, on second thoughts, wouldn't we be out of a job then?  Actually, there are methods to create such conforming code, via evolutionary programming but for now, we'll just do it our own way.

This is what we end up with for the two methods in question:
 /**
  * @param bands
  *            a set of relative frequencies for the index values 0, 1, ...
  */
 public void setBands(int... bands) {
  this._bands = bands;
  int count = 0;
  for (int i = 0; i < getBands().length; i++)
   count += getBands()[i];
  setTotal(count);
 }

 /**
  * The behavior of this method depends on whether any bands were defined for
  * this randomizer. If bands were defined, the result is an index into the
  * bands. If bands were not defined, the result is a number uniformly
  * distributed between 0 and {@link Integer#MAX_VALUE}. In both cases, the
  * superclass method {@link RandomGenerator#nextInt(int)} is called.
  * 
  * @return the "index" as defined above.
  */
 public int nextIndex() {
  if (getTotal() > 0) {
   int randomizer = nextInt(getTotal());
   for (int i = 0; i < getBands().length; i++) {
    randomizer -= getBands()[i];
    if (randomizer < 0)
     return i;
   }
   return -1; // logic error
  }

  return nextInt(Integer.MAX_VALUE);
 }


Of couse it isn't necessary to do test-driven development as shown above.  It's perfectly valid to write the method and then do the testing.  But it can actually be easier and more obvious what's going on when you do it this way.  And, moreover, your unit tests then actually become documentation on how your methods should be used.

Finally, you need to test for coverage.  The full suite of tests that I've defined above is not really a complete set.  There is a lot more we could test for.  But let's see what sort of coverage we get, by running EclEmma, another Eclipse plugin that I find works very well.  You might prefer Cobertura or one of the others.  Come to think of it you might prefer other test runners than JUnit.

EclEmma tells us that things aren't too bad: 356 covered instructions, 4 missed.  I think we could do rather more testing of the nextIndex() method, perhaps using a greater number of trials than 100,000, maybe with a greater number of bands.

Tomorrow we're going to look at unit testing private methods and also search for bugs and code smells.

OK, back to work!

Monday, October 15, 2012

My process for developing software: creating a simple class

This is the first of several blogs that outline the way I like to develop (or modify) code. I'm talking in particular about Java development using Eclipse, although most of what I'm saying should be generally applicable.

In just about every phase of development, I avoid typing as much as is possible.  Not only is typing relatively slow (although I'm fairly quick myself) but it is error-prone.

And bear in mind that this is a personal view - I don't expect everyone to agree with it in every detail.  Also, I am going to discuss certain tools but there are usually alternatives to those specific tools that do something similar.  For example, I am using Eclipse Indigo.  I haven't manage to get Juno to behave properly yet.  And you may prefer IntelliJ or something else.

So, let's get started.

For now, let's assume that you are developing a new class (or class family that implements a new interface) and you're starting pretty much from scratch.

Before I do anything else, I naturally search the web for something similar.  Anything that is some sort of utility code has almost certainly been done by someone else somewhere.  This is especially true of anything to do with Collections.

So, let's assume that we couldn't find anything suitable (or we just didn't like what there was).  As an example, we're going to develop a "wheel of fortune" class which we will call Randomizer.

Unfortunately, in the early days of Java, they didn't "eat their own dog food" and did not create interfaces to define many of the standard classes.  java.util.Random is a case in point.  So the good people of Apache created an interface called RandomGenerator which does define the methods we want.

So, we will start by creating a new class Randomizer and have it implement RandomGenerator and Serializable.  But we will arrange for it to delegate its random number generation duties.

In the spirit of avoiding typing I try to include things like comments and constructors.  But I never want a main program (well, maybe once in every few hundred classes) and, because we're going to delegate the random number generation responsibilities, we will not for now implement the inherited abstract methods.

This is what results:


/**
 * Phasmid blog sandbox
 * 
 * Module: Randomizer
 * Created on: Oct 15, 2012
 */

package phasmid;

import java.io.Serializable;

import org.apache.commons.math.random.RandomGenerator;

/**
 * @author phasmid
 * 
 */
public class Randomizer implements RandomGenerator, Serializable {

 /**
  * 
  */
 public Randomizer() {
  // XXX Auto-generated constructor stub
 }

}

Randomizer is underscored in red in Eclipse because it doesn't implement those abstract methods.  Let's talk about warnings now.  I have Eclipse give me just about every possible warning.  Everything which by default is ignored, I change to warn.

So, first we go to the constructor and replace the comment with:

super();


Yes, I know that it isn't necessary but, to me, a constructor without anything in it looks naked.  Now we click on the constructor and invoke the Change Method Signature refactoring (Alt/Shift/C in Eclipse).  We're going to add a parameter called random of type RandomGenerator.  The default value doesn't matter because nothing calls the constructor yet so null will do.  But if the constructor is in use, I usually try to name the parameter with the same name - that might just match the appropriate identifier in the caller or, if not, it will at least be clear what's needed.  I'm all for naming identifiers according to context, but something that might be passed from one constructor to the next will usually only need one universal name.

At this point, the parameter name should be underscored in yellow (a warning showing that this is an unused parameter in a non-overridden method).  [In the Preferences->Java->Compiler->Errors/Warnings->Unnecessary dode->Value of parameter is not used, I have unchecked the checkbox for Ignore parameters documented with @param tag.

So now I click on the parameter name (random) and invoke the quick-fix (Ctrl/1), selecting the Assign parameter to new field option.  For some reason I don't understand, the options you get when you hover over the warning do not include this most obvious solution.  The quick fixes are like that - very inconsistent and frequently missing the most obvious solution.

So, with a (private and final) field named _random defined, this is what the contents of the class look like now.

 private final RandomGenerator _random;

 /**
  * @param random
  *            XXX
  * 
  */
 public Randomizer(RandomGenerator random) {
  super();
  _random = random;
 }

We will eventually clean this up but not just yet.  We've got warnings (underscored here) and we are going to address those immediately.

We click on _random and invoke the Source -> Generate Delegate Methods option (Alt/Shift/S).  This fills in all of our delegate methods and, since the field implements the same interface as the class, our error goes away.

But we end up with some warnings for every reference to _random.  This is because it is an instance field and we have not prefixed the references with "this."  Up until a few years ago, I always wanted to suppress those qualifiers.  But now, it seems to me that they add some clarity and do no harm.  Here's an Eclipse annoyance: if we choose the quick fix "create getter and setter", it works well.  But if you later add more references, you can't convert them all to use the getter at the same time.  BTW, I make the getRandom() have private scope since it would be overkill to have the class implement the interface and have public access to a field that does the same thing.

We're left with three warnings: two references to _random which need to be qualified.  And the fact that we haven't got a serial UID.  All three of these problems can be easily fixed with quick fixes.

A bit of (automatic) cleanup [we'll talk more about this later] and we have the following code:
[starting with]

 /**
  * @param random
  *            XXX
  * 
  */
 public Randomizer(final RandomGenerator random) {
  super();
  this._random = random;
 }

 /**
  * {@inheritDoc}
  * 
  * @see org.apache.commons.math.random.RandomGenerator#nextBoolean()
  */
 @Override
 public boolean nextBoolean() {
  return getRandom().nextBoolean();
 }


[and ending with]

 /**
  * {@inheritDoc}
  * 
  * @see org.apache.commons.math.random.RandomGenerator#setSeed(long)
  */
 @Override
 public void setSeed(final long arg0) {
  getRandom().setSeed(arg0);
 }

 /**
  * @return the random
  */
 private RandomGenerator getRandom() {
  return this._random;
 }

 private static final long serialVersionUID = 1238102722233258232L;

 private final RandomGenerator _random;



Next blog: test-driven development.

OK, back to work!

Thursday, October 11, 2012

Method scope

I want to talk in this blog about an aspect of Java that is often paid little attention: method scope.  My way of doing things might not be 100% mainstream, but I believe it makes good sense.

If your class extends a super-class, then you obviously will not be able to reduce the scope of any methods.  Should you widen the scope of any super-methods?  Probably not.

What about non-overridden methods?  If the method is defined by an interface, then it must be declared public -- end of story.  But should any other methods be public?  Well, let's think about how methods in our class will get invoked.  One mechanism of invocation is via reflection, in particular, introspection.  Introspection looks for public methods with names of the form:
  • boolean isX() and its mate setX(boolean);
  • T getX() and its mate setX(T).
These are known as "bean" methods, or property descriptor setters/getters.  Any such method can be invoked by reflection, in particular by inversion-of-control-container (dependency injection) type configuration.  So, if you want these properties to be settable by reflection, you need to declare them public.  There's only one snag with this mechanism: Java doesn't provide any way to mark these bean methods as discoverable (and invokable)  via reflection.  You just have to "know." In practice, there may also be other reflection-invokable methods such as void addX(T) or void putX(String,T).

If you have these reflectible methods or other non-overridden methods that you want to be invoked from other classes by the normal calling mechanism, then you need to declare them public and, if the method receiver type will normally be an interface, then they must go in the interface.

What this implies is that, for a class that will normally be referenced via its interface (thus appropriately hiding the specifics of any concrete class), the only public methods in that class will be the bean methods and the interface methods.  No other method needs to be declared public because there will be no way to invoke it.

Meanwhile, what about protected and default scope?  I tend to use protected scope only for methods that are used internally (that's to say they are invoked by a base class) and declared either abstract or with a trivial default behavior and which are expected to be overridden by concrete classes to define class behavior. Occasionally, I will define a concrete non-overridable method as protected when I am sure that I only want it to be invoked by sub-classes.  And, typically, the only need for default scope is when you create an inner class within a class and you want to create a method which will allow communication between an inner class and its outer class.

Everything else should be declared private.  I like to use long names for private methods which thus give a good description of what the private method does (naturally, it only does one thing!).  I do not create javadoc annotation for private method or fields because I typically filter out all private objects from the resulting javadoc.

I also feel that private methods should not normally handle any exceptions.  Exceptions should be handled at a level where handling is either required or opportune.  Therefore, private methods may have a long list of thrown exceptions, as required.

And while good practice suggests keeping short parameter lists for public methods, private methods can use as many parameters as they please.

Finally, a word on the other method modifiers, apart from scope.  Marking individual methods as final is unusual, but is necessary in certain cases, for example delegated callback methods.  And what about the distinction between class methods (static) and instance methods?  I have the Java compiler configured to warn me about methods which can be defined as static, but aren't.  This is very useful and something which I have long looked for.  I feel that declaring a method as an instance method when it really should be a class method is just plain wrong because it implies a dependence on this when none exists.

OK, back to work!

Wednesday, October 3, 2012

Variables considered harmful

When I look through other code written by other developers, I'm often shocked at how often I find variables used when there is no reason for them to be variable.

Let's take a look at this awful specimen:

public class VariablesConsiderHarmful {

 public static void main(String[] args) {
  new VariablesConsiderHarmful().doYourStuff(args);
 }

 /**
  * @param args
  */
 private void doYourStuff(String[] args) {
  // Do some initialization
  
  String x = null;
  String y = null;
  if ("x".equals(args[0]))
   x = args[1];
  if ("y".equals(args[0]))
   y = args[1];
  if (x == null)
   x = "xxx";
  if (y == null)
   y = "yyy";
  
  System.out.println("x=" + x + ", y=" + y);
 }
}

Let's suppose that the middle section of doYourStuff  (between // do some initialization and the System.out.println line) is much longer and more complex than I've suggested here.  Naturally, you would like to refactor it into a private method getXY().  But if you do that, you will find it is impossible due to there being two returned values (x and y).

How about refactoring into two private methods: getX() and getY()?  The code is so convoluted (believe me, I've seen much worse) that it is very difficult to separate the definition of x from the definition of y.  That's largely because of the way they have been expressed, quite unnecessarily, as variables.  And yet, there never was any reason to make them variables. I believe this idea of declaring all of your variables at once and later filling in their values is a relic of the bad old days of programming in languages like FORTRAN IV where everything was a variable (even things that you think are constants).  But we going back 30+ years now.  Why would anyone program this way in Java today?  Yet they do!

Apart from obfuscation, there is a serious danger in this manner of coding: it's easy to miss initializing something because of a logic flaw.  If you have the appropriate Java warning turned on, it will warn you in the case where you initialized the variable with null (implicitly or explicitly).  But I've seen cases where the variable was initialized with an empty String even though that empty value would be invalid.  The compiler can't protect you then from your own folly.

Let's clean up the doYourStuff method somewhat:

 private void doYourStuff(String[] args) {
  // Do some initialization

  final String x = "x".equals(args[0]) ? args[1] : "xxx";
  final String y = "y".equals(args[0]) ? args[1] : "yyy";

  System.out.println("x=" + x + ", y=" + y);
 }

Isn't that so much more elegant?  If you want to, we can easily create a getX() and getY() method using our "Extract Method" refactoring twice.

Yes, of course, some of you will be thinking that we should be using Scala or some other functional programming language where variables are the exception rather than the norm.  I totally agree.  But let's try to avoid using variables when variability serves no purpose whatsoever!

OK, back to work!

Friday, September 28, 2012

Why is it important to have a source format style?

Source formatting style seems like such a minor thing. I like one format for code, my colleague likes another style. Live and let live, right?

Unfortunately, it's not quite so simple as that, at least not when you might both be making changes in the same source code.

One of the trickier aspects of working as a team is that there will occasionally be conflicts in source code. This is especially true in an agile environment. Of course, you do your best to ensure that classes are as large as they have to be and no larger. That can help avoid unnecessary conflicts.

But there are likely to be some classes that are being frequently updated and if you and your colleague are both making changes, it's really important to agree on a common code format style. That's because differences even in white space can really complicate the set of conflicts and therefore make a merge much harder. And anything which is harder is more prone to errors.

Otherwise, let's say you make a change and check it in with your favorite formatting (X) applied. Meanwhile, your colleague is making changes using his favorite formatting (Y). When he comes to commit his changes, he's going to find that the file changed on him. He has to merge. He's going to hate it when there are lots of insignificant white space changes.

He's going to hate it even more if, for example, you've put in curly braces everywhere that they're legal and, under Y, all unnecessary curly braces are removed.  There are a million ways to adjust the formatting of source code.

So, pick one style, and set up Eclipse or your favorite IDE to apply the formatting changes whenever you save.  Then, before you commit your code, actually go in and do cleanup (you can run cleanup on your entire source tree at once).  If you always follow that plan, it will ensure that the changes (and conflicts) that show up are exactly what the difference should be -- neither more nor less.

OK, back to work!

Thursday, September 27, 2012

Exception Handling

One of the surest signs of generally bad programming style, in my opinion, is improper exception throwing and handling.

Those of you who grew up with Java don't know how lucky you are to have a well-thought-out scheme of exceptions to deal with.   I wouldn't say that Java has perfect exception capabilities but they're reasonably close.

So, what is it that I think is so bad?

Here is an example of something that is just awful (but fortunately rare) -- I think everyone would agree:
public class BadExceptionHandling {

 public static void main(String[] args) {
  double total = 0;
  for (int i = 0; i < args.length; i++)
   try {
    total += Double.parseDouble(args[i]);
   } catch (NumberFormatException e) {
   }
  System.out.println("Total: " + total);
 }
}

I invoked this application with arguments 1, 2.5 and d4.  The d was a typo of course.  But instead of warning me that all is not well, the application gaily prints out:
Total: 3.5

The problem of course is in the "eating" of the NumberFormatException.  Why bother to catch it (it's actually a RuntimeException so you don't need to) if you're simply going to eat it?

Here's an improvement in the main method:


 public static void main(String[] args) {
  double total = 0;
  for (int i = 0; i < args.length; i++)
   try {
    total += Double.parseDouble(args[i]);
   } catch (NumberFormatException e) {
    e.printStackTrace();
   }
  System.out.println("Total: " + total);
 }

 The result is now:
java.lang.NumberFormatException: For input string: "d4"
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1241)
    at java.lang.Double.parseDouble(Double.java:540)
    at robin.BadExceptionHandling.main(BadExceptionHandling.java:22)
Total: 3.5

This is better -- just.  It shows that an exception was thrown.  But it still prints a total without a care in the world!  That "total" is simply invalid and should not be presented to the user at all.

However, at least in this case we were in control of the user interface (such as it is) because we were programming in a main method.  But, realistically, how many of you ever program main methods other than perhaps for testing purposes?  Basically never.  Everything that the average Joe Programmer does is meant to be invoked within a much larger system, a web application typically, but it could be a database, some sort of server or whatever.

The point is that when you are writing a method which is not a main method, you do not have the appropriate privilege to print stack traces or, worse, eat exceptions.  You have a responsibility to do something with the exception.  Most of the time, that something is simply passing it back up the stack frame.  But it could be wrapping it in another exception in order to provide more context regarding the circumstances of the error.  It should never be to print a stack trace, which will likely end up in some obscure log file, and carry on as if nothing had happened.

Let's see what I mean in the following where I have refactored by creating a method:
public class BadExceptionHandling {

 public static void main(String[] args) {
  try {
   System.out.println("Total: " + addArguments(args));
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 /**
  * @param args
  * @return
  * @throws Exception
  */
 private static double addArguments(String[] args) throws Exception {
  double total = 0;
  for (int i = 0; i < args.length; i++)
   try {
    total += Double.parseDouble(args[i]);
   } catch (NumberFormatException e) {
    throw new Exception("Problem adding argument " + args[i] + " to current total " + total);
   }
  return total;
 }
}

And the result is as follows:
java.lang.Exception: Problem adding argument d4 to current total 3.5
 at robin.BadExceptionHandling.addArguments(BadExceptionHandling.java:37)
 at robin.BadExceptionHandling.main(BadExceptionHandling.java:20)
I wouldn't normally throw an instance of Exception (I would typically sub-class Exception and throw a new instance of that) but that isn't important here.  What is important is that our main program was able to behave properly (simply show the stack trace without attempting a total).  And our method appropriately handles the NumberFormatException, and declares that the (checked) exception can be thrown.

Is that so very hard?

OK, back to work!

Friday, October 21, 2011

A somewhat bizarre exception

Have you ever seen this error?

java.lang.SecurityException: Prohibited package name: java.lang
It was tough looking it up on the internet. Usually, there are many postings about any one error message or exception. But not in this case.  Actually, the explanation is quite accurate and helpful, providing that you believe it.  It says that you've created a package called java.lang in your project, which is not allowed.  nevertheless, you probably didn't mean to do that so you may be mystified by the description.

I suppose the villain of this particular piece is the otherwise-wonderful Eclipse. Eclipse allowed me to (inadvertently) create the java.lang package in my project when I sub-classed a class in java.lang. Many of those are final so can't be extended thus you won't often run into this problem (it's taken me about 16 years!).  And in any case, the package only defaults to that of the sub-class when you click New in the type hierarchy window.  In and of itself, having a java.lang package is not fatal. Eclipse will run it.

But if you create a jar file with that class in it, you cannot add the jar file to your class loader -- the exception mentioned above will be thrown.

OK, back to work!

Monday, February 28, 2011

Things that Java got wrong, part 2: interface method bodies

The concept of the interface in Java is undoubtedly one of the best things about the language.  It almost, but not quite, makes up for not having pure multiple inheritance.  I particularly like the fact that you can define zero or more method signatures as well as zero or more constants.

But why not allow abstract method bodies?  If that sounds like a contradiction in terms, let me try to explain.  I'm using the term abstract in the sense of non-concrete.  Let's take an example.  You define an interface called SetOperable<T> and you define the following methods:

public abstract SetOperable<T> intersect(SetOperable<T> s);

 public abstract SetOperable<T> union(SetOperable<T> s);

 public abstract Collection<T> members();

 public abstract SetOperable<T> clear();

 public abstract SetOperable<T> add(T t);
Now, whereas you want to be able to implement the set operations on any type T, you are clearly going to have to define, in a concrete type, either the intersect or the union method.  But the other method is normally derivable in terms of the first.

So, in Java, you must create an abstract class which implements the required interface and which looks something like the following:

public abstract class SetOperable_<T> implements SetOperable<T> {

 @Override
 public SetOperable<T> union(final SetOperable<T> s) {
  final Collection<T> temp = new ArrayList<T>(members());
  temp.addAll(s.members());
  final SetOperable<T> intersection = intersect(s);
  final SetOperable<T> result = intersection.clear();
  final Collection<T> duplicates = intersection.members();
  final Iterator<T> iterator = temp.iterator();
  while (iterator.hasNext()) {
   final T t = iterator.next();
   if (duplicates.contains(t)) {
    iterator.remove();
    duplicates.remove(t);
   }
  }
  for (final T t : temp)
   result.add(t);
  return result;
 }
}

Concrete classes will extend this abstract class, defining the details of intersect, members, clear, add, etc.  But it would be so much nicer to be able to define this union method in the interface itself and not have to bother with an abstract class, assuming of course that you can define the method in terms of the interface (or its super-interfaces).  Scala allows you to do just that, at least in its own way, but not Java.

I admit that it's not the end of the world, but it can be awkward if you have a concrete class that should extend some other type as well as extending the above abstract class.  You can't have it extend both.  In the given example, you might want your concrete class to extend AbstractSet, for example.

OK, back to work!

Thursday, September 16, 2010

Old farts

I picked up a link (from the DZone and javablogs) to a wonderful presentation by "Uncle" Bob Martin on "bad" code and, by implication, good software practice.  Turns out that Bob Martin began life as a software professional in 1970.  That makes him even older than me (or perhaps he just started work earlier).

I wrote my first line of code in 1967, on a "Hollerith" card that had perforations that allowed us to make holes with a pencil.  We'd send the cards up to London and a week later (yes, I am not making this up), we got the results back.  My first program was to solve the equation x = sech(x).  I probably took about 12 lines of code (that's to say 12 cards) but I don't remember exactly.  The only error I made was in the comment (see below) where I declared that the program was based on Newton's method of "apprnximation".

But after programming more or less full-time for about nine months in 1969 (and getting paid for it), I took time out to get my undergraduate degree where I did almost no programming whatsoever.

So, I recognize Bob Martin as a fellow "old fart" who has been through the trenches, like me.  He gives a damn good presentation and my hat is off to him!

I found myself agreeing with him so wholeheartedly that it made me look back with quite some frustration at all of the times that I worked so hard to advocate good coding practices, only to be fought tooth and nail.

I remember back in 1984 for instance, a certain programmer whose name I will omit although it is burned into my memory, wrote a function (we didn't call them methods in those pre O-O days) that was more than 3,000 lines long!  What was even sadder was that he didn't think there was anything amiss, and neither did his manager (my peer).

Then there were all those arguments about comments in code.  I adhered to the view that if the code needed to be commented there was something wrong with it.  And, worse, the comments were likely to become out of date as programmers changed the design but neglected to make the corresponding changes in the comments.  Others disagreed vehemently.

And then do you remember all that stuff about Yourdon and "Structured Programming" (De Marco et al?).  Those guys were living in cloud cuckoo land.  But you couldn't say so in front of one of the managers who thought that such techniques were the proper way to write software.

Gee, I'm just getting started.  I remember all those battles I had about "Q/A".  The worst of these were not that long ago: in around 1992 and the years following.  I wanted to concentrate on automated testing (we would call this unit testing nowadays) but that was met with huge skepticism.  I had even developed a unit testing methodology of my own to support it.  Not reliable enough I was told -- you needed real people to sit there and push buttons.  Aaargh!

What my opponents in this debate failed to realize is that the inevitable time lag between a software release and Q/A's testing of it means that, almost by definition, it is constantly in a broken state.  As soon as you try to go back and fix any bugs, the underlying software has already changed and you are extremely likely to create new bugs.

The modern "agile" approach with continuous integration, scrums, etc. minimizes this latency effect by early detection of problems.  It's the only sane way to go.

I could continue and maybe I will in another blog entry.  Meanwhile,


OK, back to work!