Anti-patterns: improper inheritance.

While examining some other code I’ve encountered a bunch of stuff which makes me wonder what they’re teaching people nowadays in school. Rather than silently complain about the problem to my co-workers, of course I decided instead to use this forum to rant.

Today’s anti-pattern: improper inheritance.

The problem: A class ‘ClassA’ is defined which contains two features–call them ‘feature 1’ and ‘feature 2’. A class ‘ClassB’ needs to adopt ‘feature 1’ in ‘ClassA’, but also add new features which are somewhat orthogonal to the functionality in ‘ClassA’, ignoring ‘feature 2.’

When a software maintainer comes around to change ‘feature 2’ in ClassA, he finds that ClassB breaks–ClassB was written in such a way as to hide or never initialize ‘feature 2’ within ClassA in the first place.

Why this happened: The software developer writing ClassB saw some of the code he wanted to reuse, but rather than deal with the problem of properly abstracting ‘feature 1’ out of ClassA, he instead took advantage of subclass-level visibility of the internal fields in order to bypass ‘feature 2’.

What the developer should have done: Take ‘feature 1’ out of ClassA and create an abstract super-class ‘ClassC’, then rewrote ‘ClassA’ and created ‘ClassB’ to inherit from ‘ClassC.’ Thus it’s clear that the functionality in ‘feature 2’ isn’t used in ClassB, and ClassB doesn’t have to rely upon supernatural knowledge of ‘ClassA’ which could be broken in an upgrade or bug fix.

What this illustrates: A class in object oriented design should be a self-contained unit of functionality. If a class is well designed, it should have well-designed extension points and a well-designed feature set which acts as a single unit.

When well designed, other classes do not have to rely upon super-natural knowledge of the implementation of a class in order to operate correctly; the implementation knowledge–while relatively transparent so that users can know how the black box should operate–should be implemented as if it were a black box.

When a subclass has to rely upon supernatural knowledge or relies upon knowing which calls touch certain internal states related to a feature that the subclass doesn’t want to enable or use, then this clearly shows the need to refactor the superclass.

Buzzword Compliance Library

So I’m looking at someone else’s code, and they make extensive use of a particular jar file. Time to poke around and figure out what that jar file is.

To paraphrase the info page, which should tell me what the library provides:

FooLib is an enterprise-class open source library to help deploy and integrate services in a service-oriented architecture. FooLib can help you decrease development complexity while improving end-user experience by coordinating business processes with unparalleled flexibility and reduce overall total cost of ownership.

In other words, FooLib is a module which helps my code maintain buzz-word compliance with most IT pointy-haired managers.

*sigh*

WTF?!?

Java’s Exceptions are an extremely powerful way to figure out what went wrong. Too bad many Java programmers go out of their way to hide what went wrong from their fellow developers.

If you’ve got to recast an exception:

try {
    doThing();
}
catch (RandomLocalException e) {
    throw new OuterException("Some mysterious message");
}

At least have the decency to write

try {
    doThing();
}
catch (RandomLocalException e) {
    OuterException oute = new OuterException("Some mysterious message");
    oute.initCause(e);
    throw oute;
}

That way I don’t have to chase down the rabbit hole that is doThing() to find out why it barfed.

Overheard in a meeting yesterday.

“Why would you want to work on user interface? I mean, it doesn’t take a rocket scientist to build a user interface.”

Which is why most user interfaces suck: because while in fact it doesn’t take a rocket scientist to build a user interface, it does take one to build a good user interface.

Meanwhile, out in the real world, the iPhone continues to sell extremely well despite having fewer features than all those “better” phones.

A realization about web companies.

Web sites are like iceburgs: what you see only represents 10% of the actual work. And the majority of the work looks more like internal business application development in an IT department for a non-computer software related company–which it is: the 90% includes things like fulfillment, customer service, complaint tracking and auditing.

Which is why working at a place like Yahoo!, aside from the whole ‘college dorm’ feel of the place, is really no different than working for Wells Fargo or General Electric or Disney’s IT group. The work is essentially the same.

And it’s why so many developers are excited about AJAX: it represents the ability to do desktop development within the context of a web site. That is, it represents the ability to do something more meaningful with a web site than the sort of development you’d see in an IT shop like Wells Fargo–even though by and large, most web sites do not need to be “AJAXified.”

Things that irritate me.

So I’m looking through some source code and I come across an unsatisfied reference to a library. The import package name starts with ‘org.lwes’. Custom and convention says that when you name a package in Java, you use your domain name to your company or organization, but reverse it: thus, stuff I write for chaosinmotion.com goes into the top level package com.chaosinmotion. If I’m extra tricky (but I’m not) I would create a section on my web page for each component: thus, com.chaosinmotion.UITools would be documented at http://UITools.chaosinmotion.com.

So I go to http://lwes.org, thinking I’d encounter some package maintainer for some random Java tools package–only to be greeted with the message “Living Water International – El Salvador’s web page has moved.”

Given that the code appears to be an event system (I’d guess ‘lwes’ is “Light Weight Event System”), I wasn’t expecting to encounter the Living Waters-El Salvador web site. Grrrrrrr…