Search This Blog

Thursday, January 28, 2010

Defensive Programming in Java

Something crossed my mind today and I thought of Blogging about it. Defensive programming seems to be running in my decaying grey cells :-).
Consider the following best practice,

public class Foo {
public void doSomething() {
Date date;
Bar b = new Bar(date);
....
}
}

public class Bar {
private Date date;
public Bar(Date date) {
// Create a based of the provided date
this.date = immutable(date);
}
...
}


In the above example, Bar is being safe, it is ensuring that the Date object even if passed and changed subsequently externally, will be safely used within Bar.

What I ask, is that, when working with external API, shouldn't the caller be safe as well regarding the objects it passes around ?

As an example, when one works with Streams, Sockets, Connections etc, I am of the opinion that the creator or opener of the Resource should be the one to close it. For example,

public class Foo {
public void someOperation() {
OutputStream os = ...;
try {
doSomething(os);
....
// Do some other stuff with the stream
doSomethingElse(os);
} finally {
os.close();
}
}

public void doSomething(OutputStream os) {
Bar b = new Bar(os);
try {
bar.process();
} finally {
// Closes Bar and as a side effect closes os
bar.close();
}
}
}

Now for the sake of discussion let us assume that Bar uses the Stream, but it also has a close() method associated with it. The behavior of the close() method could be to close the output stream that we created in Foo. As Bar is a third party software, one would not know the behavior of the close() method without looking at Bar's javadoc or actual code (might require decompilation). For the sake of discussion, let us say that Bar is the following code:

public class Bar {
private OutputStream os;

public Bar(OutputStream os) {
this.os = os;
}

public void process() {
....
}
...
public void close() {
close(os);
}
}

Clearly our Foo code would fail as Bar's close() method is closing out the provided stream and rendering it unusable for the code in Foo. At this time, the close() of Bar method does not do anything else apart from closing the provided stream. Can we rely on the same being the only operation performed by the close() code in the future? Can we safely agree that as long as we do not call the close() method on Bar, our code in Foo is good? Can we safely walk away knowing that we don't call the close() method on Bar?

One concern that I see is that if we do not call close() on Bar and should tomorrow a new version of Bar get included in the build that is binary compatible but has other additional resources it releases as part of the close() method, what happens then ? Maybe leakage of some sort?

For example let us say that the next version of Bar does some socket management internally as well as shown below,

public class Bar {
private Socket s;
private OutputStream os;
public Bar(OutputStream os) {
this.os = os;
this.s = new Socket(...);
}
...
public void close() {
close(os);
close(s);
}
}


Third party implementation cannot be guaranteed unless the documentation certifies the same. We cannot imagine that the behavior of the close() method will not require the closing of addition resources opened by Bar.

So how does one be defensive in development in this case ? As defensive programmers, what if we provided a stream to Bar that even if Bar attempted to close() the stream, the operation would have no effect?

The same could be achieved using decorator or maybe a Dynamic Proxies where we allow every other method to go through but prevent the closing of the provided stream by Bar.

public class Foo {
public void someOperation() {
OutputStream os = ...;
Bar b = new Bar();
// Created proxy will do nothing on close() method call
OutputStream proxy = createProxy(os);
try {
doSomething(proxy);
....
doSomethingElse(proxy);
} finally {
os.close();
}
}

public void doSomething(OutputStream os) {
Bar b = new Bar(os);
try {
bar.process();
} finally {
// This operation now will honor the close but
// prevent the closing of our stream as the proxy will
// intercept and do nothing on the call to close()
bar.close();
}
}
}

In the above example, the caller Foo is being careful and guaranteeing the integrity of the Stream, a way of immutability. I am probably being too dramatic. At the same time, I think there is value in being defensive. I also think that things work well when the creator is the destroyer :-). BTW this is coded entirely developed using BLOG SPOT's editor...wonder how many mistakes I have made...

Monday, January 25, 2010

RESTful HTTP and the Representation

I was looking at a BLOG posting by Jacob Kaplan-Moss and found his Conflating models and resources an interesting point. When working with a technology like Hibernate, if we were to have an Object like SuperHero, when retreiving the same, where do we stop the retreival and let lazy loading kick in? For example,




class SuperHero {
private List<Power> powers;
private Set<Superhero> superBuddies;
private Set<Colleague> colleagues;
private Set<Trophy> trophies;
....
}

Do we load every thing when load "Superman"? That would be quite a lot of data. What Hibernate does is use proxies that will lazily load each attribute only when asked for. One could also perform queries such that only parts of the information are returned.


If one were working in a RESTful system, when one accessed the resource, /superheroes/superman what should one get back? Would we expect the entire Superman representation? In a deeply nested model, the cost of returning such data can be considerable. I think it is important to consider the idea of lazy loading when working in REST as well and especially the word "State Transfer". I imagine one would typically want to navigate a RESTful system through different states or URLS if in HTTP. For example,




/superheroes/superman
/superheroes/superman/powers
/superheroes/superman/powers/heatvision
/superheroes/superman/superBuddies
/superheroes/superman/superBudies/Green%20Lantern

etc etc


Every Representation along the way providing information that is sufficient enough to represent the resource being queried with links to additional immediate resources. This improves the "linkedness" of your application and allows one to traverse your application by entering and leaving different states. Should you need to represent superman in his entierity, then a resource to the equivalent of /superheroes/superman/full can serve to load the shebang of information :-)