Monday February, 20 2006

Throw exceptions, don't return null    \\ coding

One of the simple coding practices that has become a pet peeve of mine over the years is the reluctance of most developers to throw exceptions. I find that many developers still like to return a null value rather than throw an exception and thats something that needs to change. There are certainly going to be situations where returning null might make some sense, but most of the time you should be throwing exceptions.

I found a fairly short article titled Diagnosing Java Code: The Null Flag bug pattern which does a pretty good job of illustrating the potential pitfalls with the null flag pattern.

One place where I see the null flag pattern used in one of the worst scenerios is with DAOs. Many applications which access persisted data will setup a data access layer which provides classes and methods for creating, updating, deleting, and retrieving data. Very often the designers of this data access layer will allow their data retrieval methods to return null values rather than throw an exception. The big problem in this case is that presumably the caller of the method isn't just hoping for a value, they are expecting a value and when a value cannot be returned that is an error case. Rather than hope that the caller properly checks for a null return value an exception should be thrown.

I know how hard it can be to break old programming habits, but this is one of those very fundamental patterns which really deserves the extra effort. Trust me, you'll be doing everyone a favor by just throwing some more exceptions.

Posted by gconf at Feb 20 2006, 10:39:05 AM PST | Permalink | Comments (0)

Thursday December, 22 2005

caching the web    \\ coding

Chris Rijk pointed out some caching ideas in his comment on my last post about some of the changes that went into Roller 2.1. I was going to respond as a comment, but it got a bit too long so I decided a new post was more appropriate.

Chris,

I agree that caching data is one way to solve the problem, but it is not the only way. I tend to consider three general approaches to caching in web applications, each has it's own benefits ...

1. Data Caching. As you mentioned, this means caching your objects rather than caching rendered content and you can quickly access those cached objects to render a page. This approach is ideal for very dynamic content which could be changing at any minute, like a discussion forum. However, with this approach you also spend time doing rendering on each request, which lengthens your request processing time.

2. Cache small pieces of rendered content. This is the portal approach where you are rendering lots of little bits of content and caching that, then pulling multiple pieces of your cached content together to make the full page. This is a great approach when your content is only semi dynamic, yet needs to be reused in many different ways on different pages. Unfortunately this is typically the hardest cache system to implement and requires a great level of caching control.

3. Cache fully rendered pages. This is the easiest approach and typically the fastest, you simply render the page and cache it as a whole. The problem with this approach is that your pages can't have any truly dynamic elements that change per request.

I think that depending on your application, how dynamic the content is, and how much content and memory you have you will choose some combination of the three of these cache methods.

Now, to relate this specifically to Roller. The caching in Roller is basically completely #3 at the momement primarily because the content on a weblog really isn't that dynamic. Remember, a weblog is really just a fancy name for "website" with a really easy publishing system built in. We could possibly use option #2, however our problem is that all the weblog content is user controlled via Velocity templates, so it's hard for us to figure out what pieces of content to cache. And we could definitely use #3.

There will certainly be a places in Roller where data caching is ideal, but for right now we'll probably stick with caching the fully rendered content. Our biggest problem is really just memory, we need more room for our caches as the site gets more and more content and that problem won't change whether we're caching pages or data.

Posted by gconf at Dec 22 2005, 10:41:19 AM PST | Permalink | Comments (2)

Thursday November, 03 2005

The not so private privacy of Java    \\ coding

Today I discoverd that a private variable in Java didn't mean exactly what I thought it meant.

We recently ran into a bug in Roller that was derived from the fact that Hibernate 3 doesn't like it when you access member variables directly rather than through bean style getXXX() methods. The reason for this is because Hibernate likes to use proxies and lazy loading to fetch data only when it thinks it's needed. While debugging this problem I discovered that the "private" keyword in Java worked a little differently than I had thought.

Up until now I had believed that "private" meant that access was limited to within a given object, i.e. an instance of a Class. However the truth is that "private" only limits access to a Class and whether or not the Class has been instantiated is irrelevant. example ...

public class Foo {

  private String myAttribute = null;

  public String getAttribute() {
        // maybe I want to perform some logic here?
        if(this.myAttribute == null || this.myAttribute.length() < 1) {
                return "you need to set a value for this attribute!!";
        } else {
                return this.myAttribute;
        }
  }

  public void setAttribute(String attr) {
        this.myAttribute = attr;
  }

  public void someMethod(Foo otherFoo) {

        String memberVar = null;

        // this directly accesses a member attribute of the object passed in
        // I had thought this was not possible
        memberVar = otherFoo.myAttribute;

        // this is what I would normally do and until today
        // I had thought this was required
        memberVar = obj.getAttribute();

        // or maybe you prefer to write data?
        otherFoo.myAttribute = "huh?";
  }

}

I'm not sure why I had never realized this before, it's actually written very plainly in the Java Tutorial ... "A member's access level determines which classes have access to that member, not which instances have access."

What I am wondering now is, why not provide some kind of instance privacy? Wouldn't it seem like a good idea to allow an instance to shelter it's member attributes completely? I suppose there are very few cases where the situation I mentioned above would cause problems, but still, for some reason I feel like I've lost some privacy.

Posted by gconf at Nov 03 2005, 05:48:19 PM PST | Permalink | Comments (0)

Search

The Grabbag

Powered by
Roller Version 4.0.1.1 (BSC)
© copyright gconf ... don't copy me!