Ruby Programmer/Developer

George Armhold's Blog

Data-driven webapps built with Ruby, Java & Wicket

No More Russian Dolls- Respecting the Law of Demeter

image

My colleagues and I were struggling with some test ugliness- having to construct complicated object graphs so that a particular Class Under Test could get the argument it needed at test time.  Typically, the CUT would have some call in it like:

1
a.getB().getC().getSomeField()

So in order to test something that used A, we’d need to also construct instances of B and C, and wire them all together like a stack of Russian dolls.  For many of our tests, the test scaffolding dwarfed the test proper, making it hard to tell what was really being tested.

To address this, many of our tests were using the Builder Pattern to build up these graphs.  This helped somewhat, by centralizing the construction of the objects, and it also led to some some re-use of the scaffolding code. But it still didn’t address the underlying problem of having to build up crazy amounts of superfluous objects for the test.

Anyone who’s read Refactoring, or the Pragmatic Programmer series will recognize that the Law of Demeter is in play here.  A, B, and C are too tightly coupled. We all know this is “bad”, but somehow this never really bothered me much in production code.  In the age of modern IDEs, it’s really easy to track down who is calling whom, and to re-work the code when you feel things have gotten out of hand.

The typical remedy for fixing overly tight coupling is to use encapsulation or a delegate to hide the call chain. This never really struck me as much of an improvement, as it piled yet another interface on top of the code.  Having spent too much time toiling with J2EE megaliths, I was wary of adding yet another layer.

But then when we realized what this inappropriate intimacy was doing to our tests, a light bulb went off. Adding a really small interface to class A doesn’t really bloat the code, and most importantly- it gives the test code a hook where it can mock out the single call that it really cares about, ignoring the rest.

1
2
3
4
5
6
7
class A {
    private B b;

    public String getSomeField() {
        return b.getC().getSomeField();
    }
}

Clients of A now just call A.getSomeField().  Test code that needs an A can get a very simple mock:

1
2
3
4
5
6
A mockedA = new A() {
    @Override
    public String getSomeField() {
         return "mockedResult";
    }
}

Yes, class Bis still sharing too much information here, but unless it’s causing a problem, you can leave it alone for now, and apply the same fix to it only if it becomes an issue (maybe YAGNI).

Obviously, this isn’t some new industry-changing technique; it’s been around forever.  But as a result of applying it judiciously, our test scaffolding has been drastically reduced, and tests are easier to write and understand.

No more Russian dolls.

image credit: http://en.wikipedia.org/wiki/File:Russian-Matroshka.jpg

R.I.P., Mr. Salinger

“What I have to do, I have to catch everybody if they start to go over the cliff— I mean if they’re running and they don’t look where they’re going I have to come out from somewhere and catch them. That’s all I’d do all day. I’d just be the catcher in the rye and all.”

Apple’s iPad: One Ring to Rule Them All ?

image

Like any Apple fan, I want to run out and buy an iPad today. I’ve wanted an eReader for quite some time now, and have been dragging my feet on getting a Kindle only because I wanted to see if Apple could produce something better. Notwithstanding the current lack of reviews of its text quality, the iPad certainly seems to be the more compelling device.

But there is a serious question you should ask yourself before taking the plunge. How would you feel if someone took your current computer (laptop, desktop- whatever it is you use on a daily basis) and told you that you could only install software on it that the manufacturer authorized? Do you currently check with Dell to see if it’s OK to install Photoshop or Chrome on your machine? With the iPad, that will be your Brave New World. Want to install the latest beta of your favorite program? Well, unless Apple makes radical changes to the App Store, you won’t be able to do that.

As an iPhone user, I was willing to make some concessions to Apple regarding what apps could and could not do on the device. It is after all a phone, and I want my phone to work when I use it. I don’t want the battery to die unexpectedly because some app was running in the background, or to lose my data because another app decided to scribble all over the file system. A phone is an appliance, and by and large you want an appliance to behave predictably and reliably.

But a tablet computer isn’t quite the same thing. It sits vaguely between “ebook reader” and “laptop computer”. As time goes on, I expect that laptops in general will start to look more and more like tablets. As Jobs said,

“Browsing, Email, Photos, Video, Music, Games, eBooks… if there’s gonna be a third category of device, it’s gonna have to be better at these kinds of tasks than a laptop or a smartphone, otherwise it has no reason for being.”

Right now you might use the iPad to read the New York Times while waiting for your bus, or to check your email while sitting in a café. But will you eventually use it for actual work? If the technology gets good enough, will you leave your laptop behind and starting using your tablet for everything? Once you really come to rely on it for your work, will you still be comfortable with Apple exerting total control over every piece of software you install on it?

Did you notice during the demo that when Steve Jobs went to the NY Times website, there were lots of “missing plugin” icons where the Flash ads should have been? At first I thought this was just an embarrassing mistake in delivery, but the more I think about it, the more I’ve come to believe that this was entirely intentional- a message to the NY Times directly from Mr Jobs, saying that their website will look like crap on the device until they dump Flash.

Apple’s antipathy towards Flash, and Adobe in general, is nothing new. And as much as I would love to see Flash banished from the web, this kind of complete control by Apple really worries me. Don’t get me wrong- I really want one of these devices. But I’m not so sure I’m ready to give up that much control to Apple just yet.