Go to content Go to navigation Go to search

Java coding decisions I struggle with

I picked up the new book Implementation Patterns by Kent Beck recently. Although it’s flawed in some respects, one of the best takeaways I’ve gotten from it so far is that little coding decisions come up again and again with any project, and they’re not new. You’ll write code more efficiently if you think about these decisions and decide The Right Way to solve them. When faced with the decision again you can be confident that you’ve considered the alternatives and come up with the a good solution.

There are a few of these problems that are unsolved in my mind. I still struggle with each time I hit them.

Naming interfaces and implementations

Programming to interfaces helps decouple your code and makes unit testing easier, among other benefits. I’m often faced with a situation where I have just one implementation of an interface. How should I name the class and interface? IShape and Shape (following the convention of .NET and Eclipse)? Shape and ShapeImpl (I never liked the Impl suffix)? Shape and ShapeSupport (like Spring)?

Implementation Patterns suggests a compromise. Give the good name to the primary declaration. If the code is centered around the class and uses the interface mainly for testing use Shape for the class and IShape for the interface. If there are many types of shapes and the system codes to the interface, use Shape for the interface.

I guess I’m still not comfortable using the I prefix in my code, but I haven’t come up with a good alternative naming scheme.

When do I use final?

Final indicates a variable won’t change, and gives some performance benefits. That said, when and how often do I use final? I almost never modify a parameter to a function. Should I always be marking parameters final? That seems too verbose and unnecessary. Should fields be final where possible? I haven’t been doing that either. Should locals be final if they don’t change? Or should it be used purely for performance reasons?

I currently use final where I have to (an anonymous inner class referencing a local for example), or for documentation. Marking a field final sometimes tells me it’s OK for threads to access a value without fear.

How do I organize classes into packages?

Packages have some access restriction benefits (package/default level access), and also group related classes into smaller buckets. But I haven’t figured out when I should start a new package or add to an existing one. I find that I end up with some packages that have just a couple classes and some that seem to contain 20-50.

What tells me to use sub-packages? Should interfaces be in a top level package and implementation in another? This usually leads to circular dependencies. Should I try to use a lot of packages with a small number of classes in each? Or would fewer packages make the code more approachable?

When is the right time to use assert?

I used to use asserts a lot (in C++). As I write more unit tests most of my asserts have moved out of the code into the tests. I usually use asserts instead of comments to make a statement about the current state of variable.

Sometimes my code fails in a production environment where an assert would have raised a clear error. I’ll be asked why I used an assert that’s removed from the code instead of a real test that throws an exception. Why remove this check from production code?

Should I continue to add asserts to my code? Or write a verify function that stays in the code?

Checked vs unchecked exceptions

Java’s exception declarations make it clear what can go wrong in a method. Or do they? The method can still throw NullPointerException for example, or any unchecked exception. Does the checked exception really help the caller know what to do? How do you really handle an IOException, besides logging it?

Some frameworks use unchecked exceptions exclusively. .NET got rid of checked exceptions entirely.

Should I pass up checked exceptions if I call a function that declares one? Is it easier on the caller to catch checked exceptions at key points and raise them again as unchecked?

  1. I think IShape and Shape is the best idea, because when you use something you right away know its an interface and new IShape() wont work.
    The ShapeImpl is retarded idea, why not make it ShapeImplementation? Some people just love to write extra chars, i dont.

    I auto-generate final’s for fields(since it means something), i could also for another places, but method
    public void exec(int i, String s)

    its easier to read than
    public void exec(final int i, final String s)

    I think that less is more, because many times you have to remember many things and also have to remember to ignore the final keyword since many times it means nothing.

    I use many packages, different package for implementations is a good idea. I try to have not more than 15 classes in package. If sub-class is father than package is grandfather.

    Many things are just a matter of style and you need to find out what works best for you.


    raveman    Dec 23, 01:35 PM    #
  2. Read Goetz’s book on Java Concurrency and you have some new insights on the value of final member fields in multithreaded applications. It’s a little more subtle than that a final field is thread safe (often not the case if it’s a reference to a mutable object).


    Frank    Dec 23, 02:01 PM    #
  3. Many of these things are going to depend very heavily on whether you’re building an API that others will use, or if you can refactor to your heart’s content as you go along.

    Ideally, you won’t define an interface at all until there’s a definite use for it (and multiple implementors), and you’ll be free to shuffle around your package organization as you go along (though if you’re using revision control that can’t handle moves nicely that’s a downside). But if you don’t have that flexibility.. yeah, you have to nail it down up front, and your choices might not be ideal. Any upfront design you can do will help you figure out how to split things out.

    About assert—especially since most of these checks are computationally very cheap, I say leave them in the code. They may also be in your tests, but they’re important particularly in cases where you’re checking something that might not cause an exception down the line, just wrong behavior. Tests can change and be lost or erroneously discarded, this code might be “retired” then brought back… it’s better if it enforces its own rules.

    Checked vs. unchecked exceptions: my own approach has been to try to design method contracts to avoid exceptions. I.e., either require valid input, or make handling invalid input part of the method, e.g., int parseInt(String value, int default).

    You also have sources of error that aren’t input-based—IO failures, or SQLExceptions, etc.. Often the calling code will want to handle these appropriately (even if just displaying the error to the user) so stuff like that should definitely throw checked exceptions (and yes, pass it up until you can handle it).

    I suppose (thinking about it now…) I use unchecked exceptions mostly in places where a coding or deployment error probably is at fault, and if there’s no real recovery that the calling code can achieve (reconnecting and so on). You want to throw an exception (fail fast and make debugging easy) but it’s not an error that would be thrown during normal operation.


    Rob Whelan    Dec 23, 06:57 PM    #
  4. On the issue of assert (or Debug.Assert), I came to view that it is not a very useful construct—if you need to use assert to tell you an error, then why you don’t use exception that will give you a runtime failure? If you need to use assert to just tell you the state of your code and not to inform you an error, then you might as well write it to a file.

    So I don’t like assert at all


    Ngu Soon Hui    Dec 23, 08:01 PM    #
  5. I’m trying to keep with the “most used” idiom of naming. Otherwise by now I sticked to the “Default~”, “Abstract~” for the Superclass names. But I didn’t like it. I think the Java Collections API does a quite good job of naming their interfaces to the intentions/contracts and the concrete classes adding implementation hints.

    Actually I use final everywhere possible for variables and parameters. IDEA makes this easy with an intention and FixAll… I really like the communication aspect of this as well as the compiler checking of not reusing the variable for something else. Final classes and methods don’t appear in my code that often.

    Try to convert checked exceptions into unchecked and have reasonable exception handling at the right places in the code (see the exception handling podcast of Software engineering radio). Spring does a quite nice job there with the exception translation facility for tons of SQL-Exceptions.

    I don’t use assert but guard clauses with IllegalArgumentExceptions and descriptive texts or better the NullObject Pattern.

    Kent has invited everyone to join the implementationpatterns yahoo group to discuss the style he presents in the book.

    Feel free to join.

    I have mixed feelings about the book. On one hand it is a great source for reflection (or teaching/coaching) on the other hand there are many important things missing, some discussions don’t fit and it could have had some more thorough reviewers spotting the many inconsitencies.

    (See my blog entry on the book)


    Michael Hunger    Dec 23, 09:09 PM    #
  6. The “I” has always bothered me but for lack of anything else I use it. What would be cool is if you could just @Interface from a pojo and have that work for you. Of course only on the public.


    doyle    Dec 23, 11:02 PM    #
  7. I hate the “I” for the simple reason that when you create a concept central to your system you should name the Java type based on the concept. For example, if “Shape” is a central concept for your application, there should be some type named “Shape” in the code base. When you talk to other developers on the project, you’ll talk about Shapes, creating them, manipulating them, and so on. In many cases, Shape will be an interface (although not always).

    Now, if you name the central interface “IShape”, then chances are you are not talking about IShapes (bonus points if you do—I have never seen this in practice). That is, a central concept in your system is an IShape but you purposely call it something else, “Shape”. This just adds confusion. So, I push to name things based on the concepts they represent using the vocabulary of the project/team/organization.

    As these concepts get mapped to Java types, you may make some interfaces, some classes. Using a special code for interfaces doesn’t really give you much in exchange for the added confusion (and I’ve even seen a team that named some items InterfaceShape and others IShape—and talked about neither). Don’t make your code base harder to navigate.

    Finally, if the “I” is so important, why stop there? Go full-bore for “Hungarian notation” as the old Windows stuff did.

    pszString of course, tells everyone this is a pointer to a string that is null terminated (that is, a “C” string instead of a more “normal” Pascal string). Think of the notation for a List of Map’s, each a Map of String to IShape. Have fun.


    Eric Foster-Johnson    Dec 24, 08:06 AM    #
  8. I think I have solved two of the problems, at least for me.
    The first is about interfaces where I neither like the IShape nor the ShapeImpl solution. I simply call all the interfaces “able” at the end: This way, the implementation is correctly named “Shape” and the interface “Shapeable”. Thus you will find things more simple using nowadays IDEs.
    The second is about checked vs. unchecked exceptions. In case you explicitely want to warn a programmer that your method may rise behave exceptional then force him to catch an exception. This way the code gets more stable from the beginning, even if there is more work to do. See more at http://goit-postal.blogspot.com/2007/05/thoughts-on-successful-exception.html .

    Greetings, Georgi


    Georgi    Dec 25, 01:45 PM    #
  9. My opinion about asserts:

    asserts should never be used to catch illegal values in a place where it could be expected (like params to a method). No, you would use assert to inform the reader and the runtime what you were thinking about some state when writing this code. And you should enable assertion even in production systems since it would probably not work as expected if a value is different than you had expected it before.


    Johannes Rudolph    Dec 26, 01:31 PM    #
  10. I used to mark all the parameters as “final”.
    Now I just use CheckStyle to catch all the assignments to parameters. Running checkstyle as part of integration build makes wonders :-) Checkstyle Eclipse plugin is excellent. It is fast, configurable, gives quick feedback, can be used even if the whole codebase does not confirm to your Checkstyle configuration. In fact, we have 2 Checkstyle configurations – the minimal one, which runs as part of integration build, and the ideal one, which is used by the Eclipse plugin.

    I mark local variables and fields “final” whenever I can.


    Andriy    Feb 7, 01:22 PM    #
  11. Naming conventions is just a matter of taste. I personaly use the Eclipse-style prefixes I and A, but I don’t think it’s Hungarian like. It’s just to avoid name collisions

    I use final wherever I can. Code is still readable if it is properly colored… and most of the time it helps showing design problems like parameter reassignment.

    packages is mostly a matter of taste too, if you’re not issuing an API then it is only a matter of logic.

    I do not use assert at all, as it is a disable-able feature. Better use parameter checks, and debug mode to follow variable values.

    The rule of thumb for exceptions is :

    - do not throw if you can recover inside the method

    - throw checked if another method can recover

    - throw unchecked if there is no way/no use recovering from it


    mauhiz    Jun 11, 10:11 AM    #
  Textile Help