Archive for December, 2007

George Mitchell States the Obvious

Yeah, nobody saw this one coming…

Mitchell Report

Next thing you know, we’ll find out professional athletes use drugs. Yeah, right.

In-Memory Map Compression?

Suppose a Java app retains a huge HashMap in memory. The map keys are strings, and its values are simple classes holding various display attributes such as label, tooltip, preferred width, and other display attributes.

While the in-memory storage is fast, the maps are very large and consume a lot of RAM. Most of the data is text, however, and there are many similar, although not identical, tooltips and labels. So I’m wondering if anybody ever implemented in-memory map compression? Kind of like an in-memory ZIP archive?

Maybe this isn’t specific to maps, but rather a general-purpose in-memory Java object compression mechanism? It seems like any time you have a cache containing tens of thousands of objects, perhaps the cache could compress the data internally?

It’d probably be easier to just move this to a database, and then perhaps cache frequently accessed objects in memory, rather than worry about compression. Anyway, it’s just a random (geeky) thought.

Questioning Dogma

I am an increasingly skeptical developer. Things that make me think twice…

Shouting
  1. Whenever someone whips out the “premature optimization is the root of all evil” quote. I think most programmers do not realize this quote is taken out of context. The quote refers to “micro-optimization”, not large-scale architectural decisions. Many performance-related decisions DO have to be made early in a project. Thinking about performance is not the same thing as obsessing over micro-optimization.
  2. On a related note, many people (in classes I teach) are resolute in their belief that ORM tools like Hibernate or JPA are simply too slow. Sigh. These people are obsessing over performance too much, as opposed to ignoring performance considerations.
  3. Striving for 100% code coverage when testing. I’ve discussed this before, and subsequent comments and discussions have led me to believe that 100% code coverage is not all that important. It is probably more important to demand better tools that ignore trivial code, to ensure we do test things that really need testing. Filtering out “trivial” code and alerting us to complex code that probably SHOULD be tested…now that’s an interesting problem!
  4. Whenever people argue for or against Ruby/Rails, I am skeptical. Sorry, but the claims (on both sides) are just too nutty and people are too passionate to be objective. It’s not that black and white. Let’s just sit back and watch the comments this provokes…
  5. I feel the same way about Linux, Mac, and Windows. These are such heated topics that I tend to be skeptical of everyone. In fact, too much fan-boy-ism is a repellent for me.
  6. People who preach against Big Design Up Front (BDUF). Be careful, for many of these people warp the theory into “no design is ever good”. I’m no fan of BDUF, but I certainly think about many aspects of design very early on! For example, if I know my app needs to store billions of records, you can be damn sure I’ll be thinking about storage options and sorting algorithms from a completely different angle than for an app storing 300 records.
  7. The notion that unit tests are THE documentation. Uh, no. Tests are for testing. They have a happy side effect of serving as good examples, and I often refer to tests to learn how to exercise an API. But to argue that the whole point of writing tests is to create documentation…that seems wrong to me.
  8. Speaking of testing, people who rail AGAINST testing make me wonder…has this person EVER written a test? Maybe they make good points, but to NEVER write tests borders on incompetence.
  9. XML is all evil, all the time. Wrong.
  10. Ant sucks! Maven rules! Wrong. Or…Maven sucks! Ant rules! Again, wrong.
  11. YAGNI. To a certain extent, but you still need to anticipate and plan for the future.
  12. We need to lock down PCs. Restrict Internet access. Force procedures. Ick. Those things make me unhappy and I am very skeptical these techniques work. In fact, I believe as you clamp down on people, the best and brightest will leave.
  13. SOAP sucks! Web services suck! Yes, I agree. (what did you think I’d say???)

What are you skeptical about? Hopefully someone says no-name bloggers with over inflated egos… :-)

Notepad Still Sucks

The bundled applications…Notepad, Paint, etc…are the biggest Vista disappointments. Complete. Lack. Of. Innovation.

Notepad Still Sucks

Anyone have a better theory?

Ballmer Tongue
Crap

Legacy-Proof Your Frameworks

You know the drill. You design a perfect framework, release it to a group of programmers, and receive rave reviews. Yeah! Then you start version 2, but discover all those happy customers are actually using your API in ways you never intended…or imagined.

Public API

Sure, it’d be nice to rename that method…but you cannot, because that will break someone else’s app. Every time you change something, other programmers have to update their own code, which costs money and time. Features quickly become frozen and virtually impossible to change. You now have legacy code. What happened?

Minimize and Segregate

This article examines two goals when sharing code. First, you should make the public API as small as possible. The fewer things you share, the less tightly coupled clients are. If you share a public API with 500 members, clients have 500 potential connection points to your framework. An API with 20 members has far fewer couplings with client code.

Second, you should segregate public code from “private” code. Make it very clear which parts of your framework clients are supposed to use. In some cases, you can introduce barriers that make it harder for clients to accidentally use internal implementation details.

Hopefully you can guarantee stability with a very small, well-segregated public API, and retain some freedom to improve hidden implementation details behind the scenes.

Minimize Visibility

We’ll start with an easy one. Rather than blindly writing public getters/setters for every field, only expose what you really need. Use the private keyword liberally; only use public for things that need to be available to callers.

Basically, minimize visibility whenever possible. This helps keep your public API small.

Hide Behind Interfaces

Interfaces provide another mechanism to hide internal implementation details. Programmers commonly define interfaces with accessors:

public interface Name {
  String getFirst();
  String getLast();
}

As you can see, the Name is immutable. We don’t see constructors in interfaces. Interface-heavy APIs play nicely with dependency injection tools like Guice or Spring and can significantly reduce the need to code directly against implementation classes.

Use an impl Package

Interfaces need implementations. Where do these go? And what about “helper classes” like LangUtils or ComparisonHelper?

I recommend putting implementation details into an explicitly-named impl package. This gives a clear cue that everything in that package is an implementation detail that may change in future releases.

Keep in mind that Java packages only provide a hint to programmers. It is very likely that many classes in your impl package need to be public in order for other parts of your framework to use them.

Provide Static Factories

So how do you encourage people to only use public interfaces but avoid classes in the impl package? You could encourage them to use dependency injection. Or, you can borrow a technique from the Glazed Lists project. Check out the GlazedLists class.

This is a class in the “public” package with static factory methods that return interfaces. Internally, however, these factory methods construct implementation-specific classes from non-public packages.

Although this does not guarantee programmers avoid implementation details, it does provide an officially-supported mechanism to get to the implementations.

Use Exotic Class Names

Taking the impl package one step further, you might want to name implementation-specific classes using awkward names like _MyApiImpl_LangUtils. It is quite easy for programmers to inadvertently include an impl package in an import statement.

But seeing a butt-ugly class name like _MyApiImpl_LangUtils directly in the source code makes it significantly more obvious that programmers are using something they should avoid.

Include Weird Methods in Interfaces

While it is usually good to encourage interfaces, sometimes you might prefer people extend an abstract base class instead. As soon as you add a method to an interface, everybody implementing that interface is broken.

However if people extend a base class, you can add new methods to that base class without (usually) affecting people.

For Example…

Check out the Matcher code from the Hamcrest project:

public interface Matcher<T> extends SelfDescribing {
  boolean matches(Object item);

  /**
   * This method simply acts a friendly reminder not to implement
   * Matcher directly and instead extend BaseMatcher. It's easy to
   * ignore JavaDoc, but a bit harder to ignore compile errors .
   *
   * @see Matcher for reasons why.
   */
  void _dont_implement_Matcher___instead_extend_BaseMatcher_();
}

Another Reason…

I just used this technique for another reason. I’m writing a little P2P framework and each node in the network has an Address, which is an interface. Behind the scenes, however, the framework has to downcast to an implementation-specific subclass of Address. Without getting into too much gory detail, adding a huge ugly method to the interface helps remind programmers to get their Address from my framework, rather than by implementing the interface directly.

Require a Key

This is a little hack I’m quite fond of. Suppose you have a public factory:

public class MyFactory {
  // public class, but private constructor
  public final class Key {
    private Key() {}
  }

  public static Widget createWidget() {
    return new WidgetImpl(new Key());
  }
}

Let’s study that for a bit. The Key has a private constructor, so MyFactory is the only class that can construct it. This forces programmers (unless they use reflection tricks) to go through our createWidget() method to construct new widgets.

Here is how you’d write the WidgetImpl class, ideally in an impl package:

public class WidgetImpl implements Widget {
  public WidgetImpl(MyFactory.Key key) {
    if (key == null) {
      throw new IllegalArgumentException("Please use MyFactory");
    }
  }
}

Since you cannot construct a Key (again, without reflection tricks), you must use the factory to construct new Widget objects.

(my apologies if the above has a typo or something…I’m coding in WordPress…)

Not the JarJar from Star Wars…

You might consider a tool like Jar Jar Links to hide the fact that your framework uses some specific third party JAR file.

Summary

I hope you find some of these techniques useful. Some people will always try to bypass your public API and rely on implementation details. Who among us has NEVER used some com.sun.* code in our own apps? Ahem…moving on…

The point is that framework developers need to make it very clear which interfaces, classes, and packages are considered “stable” and part of the “public” API. Good frameworks will make every effort to maintain stability of these public APIs from release to release.

Although you could rely on JavaDoc comments or simple package names, it is better to make it as hard as possible for programmers to accidentally rely on internal implementation details. Code completion in modern IDEs makes it really easy to accidentally import something from an implementation package.

The CFL Lie

You know the story, compact Fluorescent lamps (CFLs) cost more up front, but consume less electricity. They allegedly last far longer than regular bulbs, so over the lifetime of the bulb, you save money.

CFL

Well, two more CFLs just went bad in our living room. Based on my (non-scientific) observations, these things burn out as fast as — or faster than — old school incandescent bulbs. Thus, no cost savings.

Bring on LEDs…

I’ll continue using CFLs for the near future just to reduce consumption of coal generated power, but LED bulbs cannot get here soon enough. Unless, of course, low-quality LEDs end up failing as fast as CFLs.

I think the real problem here is cheap manufacturing reality versus theoretical lifespan. A well-made CFL or LED should last a lot longer than an incandescent bulb. But without any regulation or easy way for a consumer to know which products actually live up to the exaggerated claims, your mileage will vary significantly.

Just Fixed a Threading Bug…

…I think.

Now I wonder…did I really fix this thing? Or perhaps the problem occurs once per month instead of several times daily?

PacMan Fever

Too bad the Google Chart API does not let me control foreground colors for pie charts…

UPDATE: Dang! Stupid me, I read (and apparently am confused by) the docs:

Only background fill is available for bar charts, pie charts, and Venn diagrams.

Jesse set me straight:

Just Say No

I really enjoyed reading Ask 37signals: Installable software?, in particular I enjoyed reading the comments.

(I think) many of the commenters just don’t get it. I’m talking about the people who said things like…”yeah, but what if you supported feature X? My company really wants that feature! Or what about features Y, Z, and Q? Then you could get a whole bunch of new customers!”

Learn to Say No

I recall reading an article about Google’s constant internal battle to keep crap OFF the home page. Every department wants “just one more link…”. The problem is, catering to this sort of request — trying to please everybody — results in slop that delights nobody.

I think 37Signals is right. Their software is not right for everyone, but if it were, it wouldn’t be great for anyone.

Make CSS Work

Microsoft just announced the next version of IE will be called…IE 8.

Add that to my “Wow” list.

My ideas for IE 8:

  • Properly implement CSS, in particular the box model. Consistent page layout across browsers is a huge challenge.
  • Make sure Vista still works even when I have Firefox configured as my default browser.
  • Make standards modes default, not quirks mode.
  • See that search box at the top of my blog? It works in Firefox, but in IE I’d have to use a hack to get that background image to disappear when the box has focus. Fix that.

I guess the last bullet is another CSS issue. The previous bullet is probably more an issue with Microsoft web sites insisting on being IE proprietary, which sucks.

So, to summarize:

Make CSS Work.