Approaching the end of the line with school…

Last Friday, the 14th, I made a large step toward finishing my PhD – I passed the PhD Qualification Exam.  This means I’m now a PhD candidate and with just a bit more work I can write some more code, do some more testing, read more sources, and finally write a large document and do another presentation and after all that, hopefully be a PhD.  Or a doctor, but not the sort of doctor that helps people.

Java and Immutability: Creating a Simple Builder

The more I look back on what I learned about programming in school (junior high, high school, college, etc.) I realize that although it made a great base on which to learn, it really does not get you ready for problems you’re going to see in the real world.  Of course, even then the problems are always changing and what you thought was the best approach a year ago, a month ago, or even within the last hour, isn’t.

One of the largest hurdles to jump over (besides recursiveness), in my opinion, is mutable versus immutable.  The main reason is because you’re taught from the time you start programming through college (ignoring those of you who took a Haskell class) you’re only taught using C, C++, or Java.  All languages that are mutable state programming languages (yes, you can apply immutability to them and I’m getting to that) and although (perhaps) easier to learn can lead to some hard problems down the line when you have to start thinking about scalability and parallelism.  Josh Bloch, of Effective Java fame, has said that unless you have a really good reason to make a mutable class, you shouldn’t.  And if you have to make a mutable class, limit the scope of it’s mutability.

Now, as the title of the post implies, I’m going to talk about how to make immutable objects in Java and touch on some of the issues that you might run into along with how to make a builder class to instantiate this new immutable object.  There are a few conventions that you apply to an object that will normally make it immutable with a few small exceptions.

  • make the class final
  • make all fields final and private
  • if a field is mutable make a defensive copy on a get
  • only set the fields in the constructor
  • do not allow setter methods

Now, these steps will get you there but, there are a few gotchas that people normally don’t think about.  For instance, most classes with the Iterable interface or an interface that allows removal from a set or list even if it is defined as final in the class if you pass it out to the caller using this pattern:

public Iterable<SomeType> getSomething() {
  return this.myIterableSomething;
}

are in for a big surprise (unless you’re using an immutable list) because the caller can then use the remove() method on that Iterable list that you returned.

Now that you’ve got this wonderful (and hopefully) immutable class, another awesome thing you can do is make a builder class to help construct the object.  This is especially helpful if your class takes a large number of inputs into the constructor.  There are many ways to make builder classes but I’m going to demonstrate my favorite one: a static class inside of the class you want to create.

Creating the builder is really very simple.  First, have a class you want to make a builder for, in this case, let’s use SimpleClass.

final public class SimpleClass {
  private final int a;
  private final int b;

  public SimpleClass(int a, int b) {
    this.a = a;
    this.b = b;
  }

  public int getA() { return this.a; }
  public int getB() { return this.b; }
}

Now, lets create the builder class inside of the SimpleClass, like this:

final public class SimpleClass {
  .. snip ..

  public static class Builder {
    private int a;
    private int b;

    public Builder() {
      //assign some default values...
      this.a = 0;
      this.b = 0;
    }

    public Builder setA(int a) { 
      this.a = a;
      return this;
    }

    public Builder setB(int b) {
      this.b = b;
      return this;
    }

    public SimpleClass build() { return new SimpleClass(this.a, this.b); }
  }
}

With this, we now have a very barebones builder class for SimpleClass.  In practice you’d take values that absolutely have to be set in the builder’s constructor and set reasonable defaults for the optional values.  You’d then use the set* methods to set the optional values for the class.  Additionally, if you only want the user to construct objects through the builder class you can set the constructor on the class to private, leaving you with a SimpleClass listing:

final public class SimpleClass {
  private final int a;
  private final int b;

  private SimpleClass(int a, int b) {
    this.a = a;
    this.b = b;
  }

  public int getA() { return this.a; }
  public int getB() { return this.b; }

  public static class Builder {
    private int a;
    private int b;

    public Builder() {
      //assign some default values...
      this.a = 0;
      this.b = 0;
    }

    public Builder setA(int a) { 
      this.a = a;
      return this;
    }

    public Builder setB(int b) {
      this.b = b;
      return this;
    }

    public SimpleClass build() { return new SimpleClass(this.a, this.b); }
  }
}

To actually instantiate this class in practice you’d make a call like this in your code:

  SimpleClass mySimpleClass = new SimpleClass.Builder().setA(10).setB(11).build();

And, whala! You’ve created an immutable class using a builder!

With this, you’ve taken the first step toward better coding in the real world and on problems that have you dealing with scale and parallelism.  I’ll hopefully write about scale and parallelism in later posts, so stay tuned, and if you have anything you think I should write about or a place where I’ve screwed up, let me know in the comments below! :)

If you’d like this source code in a nice form, check it out on GitHub.

2012 Goals – December / Full Year Retrospective

And I made it through an entire year of doing retrospectives.  I’m not quite sure what that says about me other than I can write a few sentences on a blog one time a month updating my progress toward goals I have. :)

#1 Getting in Shape

I’m getting more in shape. Still need to start jogging again though.  I found some nice exercises about how to fix the computer guy posture that the majority of us all suffer from here.

#2 Propose PhD Topic

I’m ready to go but I’ve run into a few roadblocks and working on getting those resolved.

#3 Learn a New Programming Language

This got put on the back burner for the past few weeks with school taking a priority.

#4 Learn Guitar

I’m still going to lessons but I slacked off a bit on my week off from work to take care of house work that needed to be done.  I picked up an Apogee Jam and Rock Prodigy to help me get better at the guitar.  I’m really liking Rock Prodigy and it’s lessons that you can do while just sitting around the house.  I’m hoping to get back into a schedule where I can do the practice for it at a set time.

#5 House work

This ended up taking some of my time during my holidays to clean up my house.  It’s a lot better than it was before but there is still some more work let to be completed.  I guess this is the joy of home ownership.

Overall

I’m glad I kept this blog up at least chronicling my attempts at New Year’s Resolutions and forcing myself to act upon them, even if I didn’t finish all of them at least I got myself on a track to complete them.

2012 Goals – November Retrospective

And one more month to go this year…

#1 Getting in Shape

I’m using a personal trainer and it’s definitely a killer.  I’m feeling the burn every time I go there, so I think if I keep it up I’ll definitely be in great shape for another Tough Mudder.  I haven’t however been doing the jogging that I need to do.  So, I’ve gotta get back on the horse with that.

#2 Propose PhD Topic

Rounding up the professors is like herding cats.

#3 Learn a New Programming Language

Haven’t really had a chance to touch on this at all this month.  It’s a little depressing but I’m sure I’ll get back to it soon.

#4 Learn Guitar

The songs I’m playing are actually sounding like songs now (albeit a little slower) so I think I’m making good progress.  Still need to work on changing chords since I can only do them at Neil Young speed and not Rush or Led Zeppelin speed.

#5 Housework

Not much going on in the housework front other than trying to keep the crepe myrtles alive.

Overall

I think 4 outta 5 ain’t bad. :)

2012 Goals – October Retrospective

Think, only two more months left in the year, and lets take a look at what I’ve done so far (and maybe think about next years goals..).

#1 Getting in Shape / Prepare for Tough Mudder

I wrote about my Tough Mudder experience, and I’m going back through the Diabetic Athlete’s Handbook to figure out how to best control my blood sugar in the mess that is Tough Mudder.  I’m also stepping up my workout routine to make sure I’m not as much a wuss as last time.  I also started going to a personal trainer since I realized I wasn’t getting where I wanted to be by myself.

#2 Propose PhD Topic

The proposal is done and I’m now doing all the fun stuff that is needed to get the topic proposed (getting a room for it, etc.).  Lots of fun.  Really.

#3 Learn a new Programming Language

I’ve sort of morphed this into a learn a new programming language / learn new system architectures; and to that end, I’ve really begun reading and wrapping my head around the ideas of: CQRS, Event Sourcing, and Version Control with respect to scalability.

A good overview of CQRS can be found here: http://www.udidahan.com/2009/12/09/clarified-cqrs/

#4 Learn Guitar

I feel I’m getting a lot better at the guitar, still not amazing, but songs are actually beginning to sound like songs although I still have a lot to work on.  For instance: chord changes and strumming.  I still don’t quite have the whole rhythm thing down quite yet when having to do things like downstroke on an 8th note then down / up as 16th notes.  I’m sure I’ll get better at it; just need to fire up the metronome and make it happen.

#5 Housework

I finally got the disassembled playscape out of the backyard and removed two decorative columns in my house.  Hopefully I’ll take care of the fence and all the additional rocks sitting in my backyard so I can start planning covering my patio. :)

Overall

Lots of random events happening but, I went to ACL on Oct. 13th and saw Punch Brothers, Bassnectar, and Neil Young!

2012 Goals – September Retrospective

Just after finally posting my retrospective of last month, I’ve gone and written the one for last month.  It’s been busy (obviously) and I’m here to talk about it some.

#1 Getting in Shape / Prepare for Tough Mudder

Well, I’ll know how well I’m gonna do this coming Sunday (Oct. 7th).  No matter how I do, this is something that I’m going to have to keep up.  I’ve been working on eating more often at home and bringing my lunch from home as well.  I still haven’t found a good workout routine that has worked with my recently hectic life.  I’m hoping to figure out how to calm it all down soon enough and get into a routine that works.

#2 Propose PhD Topic

It’s still happening, I’m now smoothing out the rough edges on the proposal and getting the presentation in order.

#3 Learn a new programming language

I’m still playing with Clojure but I’m also taking a deeper look at Event Sourcing and Command Query Responsibility Segregation and thinking about making an EventSourcing framework combining the two.  Right now I’m going to write it in Java since I don’t feel my Clojure skills are awesome enough to release something like that to the world.

#4 Learning Guitar

I’m making progress, although I’d love to spend more time practicing, I’m getting about 30 minutes to an hour of practice in every other day.

#5 Housework

It never ends and I’m looking forward to removing old papers and the like from my house.  I’m hoping to just scan anything of quasi importance into my computer so it’ll live on as wasted bytes on a disk in the cloud instead of in my closet.

Overall

Life is busy and hectic but I really wouldn’t have it any other way.  I also just bottled my second beer, the Belgian Banana Beer and in a month I’ll know how it turns out.  It’s also made me start planning my next beer – an interesting take on holiday beers which I’ll talk about later :).