Jason Kozemczak http://www.cozykozy.com Adventures in software development. posterous.com Sun, 16 Oct 2011 17:46:04 -0700 A Developer's Praise of Agile http://www.cozykozy.com/in-praise-of-agile-minus-the-bs http://www.cozykozy.com/in-praise-of-agile-minus-the-bs

In case anybody was wondering where I've been for the past 8 or 9 months, I've certainly kept busy. Aside from getting engaged and buying a house, I started working for a great company in Saint Louis called Asynchrony Solutions (we're hiring). Aside from everyday work, I've also been working on a number of different side projects, some of which I'll hopefully have time to write about in the near future!

One of my biggest takeaways from Asynchrony thus far has been agile and extreme programming (XP) practices. Below are a few reasons why you should appreciate agile as much as I do:

Pair Programming

Ahh, but of course, there's no way a post about XP/agile would ignore the oft-mentioned practice of pair programming. I figured I'd go ahead and get it out of the way. I realize that there's a reason pair programming is often touted as the cash cow of extreme programming: it's pretty damn awesome.

What pair programming has taught me (and continues to teach me) is that if we can't explain our logic and thought process to an individual sitting next to us as we write the software, there's no chance in hell anybody will be able to decipher it later (btw, comments are cheating! A codebase littered with comments is probably telling you that you're doing it wrong). Pair programming in this way helps the developer determine very early the intent of the code he or she wishs to write.

Pairing helps me learn alternative approaches to problems. It allows me to gain the insight the person next to me has. As such, I've probably grown more as a software developer in the past few months than since the time when I first started writing software. Not only that, but you get to learn new keyboard shortcuts (or face humiliation of your peers!); double rainbow, all the way!

The final perk of pairing is that you often don't have to type as much. Unless you're a keyboard hog, of course.

Kanban

Kanban is system pioneered by Toyota for managing lean processes involving supply chain management (though it can be applied to many processes, including SDLC). To give a quick and somewhat trivialized description of Kanban: index cards are placed in pools on a large board. Each pool has a size limit, so that when a spot becomes free, a card can be promoted or "pulled" into the next pool.

Applying Kanban to software development, at the beginning of an iteration, we break iterations down into stories which are then written onto index cards. If the amount of effort required by the stories is greater than the team has historically been able to complete, stories can be prioritized and moved to later iterations. Once the cards for the iteration have been determined, they are all placed in the first work pool. Cards are then pulled into the next pool as they begin to be worked.

What the pools are called and represent will differ, but generally most of the Kanban boards at my company have a starting pool, an "in development" pool, a "review" pool, a "UAT/integration" pool, and a "completed" pool. Limits are imposed on each of these pools (aside from the "completed" one); these limits are often based on team size, velocity, and past history. They can be adjusted as iterations pass to better fit for the team (continuous improvement, yet another joy of agile!).

There's a significant amount of subtlety to Kanban that I'm glossing over. I recommend to RTFG if you're curious. I'd rather focus on why it works for me; one of my least favorite aspect of being a developer is that I have often in the past felt like my voice was often ignored in favor of business owners and more functional types. In waterfall-ish situations, this lead to unrealistic deadlines which were ultimately missed, at which point undue blame would be pushed onto development.

A Kanban process leaves the act of determining story length/weight up to the developer; this added responsibility gives me as a developer a greater sense of ownership, instilling the desire to meet deadlines while also making me more likely to  accurately estimate development effort (win-win for both sides!).

A subtle yet powerful psychological effect of Kanban is the feeling a person gets by "pulling" a story to work. The language used was intentional. Instead of having work pushed upon you, you as person taking part in a Kanban process must consciously pull work from the previous pool. For me, this helps with morale and also tends to reinforce the ownership I mentioned above.

Test-Driven Development

I get this sense that your everyday IT manager thinks of agile as a bunch of cowboy coders spewing sphagetti code from their six shooters bolstered at their hips. This could not be further from the truth. Agile is disciplined. Let me repeat: Agile is disciplined. It takes patience and diligence to practice agile correctly. Test-driven development (TDD) plays a big role in guaranteeing this discipline.

TDD allows developers to programmatically determine if the code we are writing is doing what we expect it to do. Ideally, every (or as many as possible) behavior of the software can be proven by a test; when a story calls for a new piece of functionality a TDD practioner will write an example (i.e. a test) proving that the software does not do the thing the story wishes it to do. He or she will run that test, and it will fail. The developer will then write the code necessary to make the system behave as the story (and subsequent test(s)) expect it to behave. The developer can stop once the test(s) pass.

This process can be repeated over and over, building up a large number of tests which help to ensure that the software will continue to perform the things it should do. If we make a change that breaks a feature of the system, a corresponding test will fail, signalling that we have taken away some functionality of the system. This quick feedback loop makes it much more difficult to introduce bugs.

My favorite part about all of this? A developer with excellent test coverage can refactor with impunity. You can refactor to your heart's content (as we probably often do anyway...), and as long as the tests pass, you can rest assured that the software is still doing the things it should do. That is an empowering by-product of TDD.

tl;dr

Agile development has a lot to offer. Though I've only lightly grazed over those areas that have most affected me over the past few months, if I've at all interested you, I suggest checking out what others who are more knowledge than me: Kent Beck, Martin Fowler, or Asynchrony's own Brian Button. There's several other tenets that I have passed by (continuous integration, release often, etc.) that are worth your time.

If you're interested in lean methods in general, I just finished Eric Ries's The Lean Startup, and I thought it was a great read. Ries gives a strong argument for utilizing agile/extreme programming in startups specifically, but the substance is applicable to businesses and organizations of all types.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/905979/untitled.JPG http://posterous.com/users/1kLvJ1zaZjfr Jason Kozemczak cozykozy Jason Kozemczak
Fri, 07 Jan 2011 19:44:47 -0800 Introducing nCoffeeScript: a CoffeeScript compiler for Windows http://www.cozykozy.com/introducing-ncoffeescript-a-coffeescript-comp http://www.cozykozy.com/introducing-ncoffeescript-a-coffeescript-comp

The wonderful CoffeeScript turned 1 (dot 0) over the Christmas break. For those who haven't heard of it yet, I highly recommend you visit the site and look/play around. You can even check out the amazing annotated source for it, courtesy of its primary developer, Jeremy Ashkenas. The documentation is incredible actually.

In case Coffeescript is new to you, it's a language that looks a lot like the lovechild of Ruby and Python, and it just so happens to compile into Javascript. If you visited the link above, you'd learn that it compiles 1-to-1 into Javascript. CoffeeScript's compiled output is well-formed and well-performing Javascript. I could go on, but it's probably best just to go to the site; it'll do a far better job demonstrating its awesome-ness.

Poor Windows Developers...

CoffeeScript's command-line compiler is implemented using Node.js; the downside to that fact is that there's no easy way for Windows developers to integrate CoffeeScript into new and existing web apps. Since CoffeeScript is actually written in Javascript, it can be compiled in the browser, but this isn't a very practical in an automated build/deploymen environment. CoffeeScript can also be compiled "on the fly" in a client's browser, but this solution is not a viable production-level option.

Another possible solution is to install Cygwin, compile Node.js, and then download/install CoffeeScript, but this path is long and difficult, and still makes compiling from Windows arduous.

nCoffeeScript to the Rescue

The obvious solution to this problem was to create my own path. As such, I've created nCoffeeScript, a CoffeeScript compiler written in .NET for Windows environments! The source can be found on Github. Get the source, build it, and try it out. Let me know what you like and what you wish you could do with it!

I consider nCoffeeScript to be at v0.1 sort of state. I spent a few hours the past two nights getting the main use cases working, but haven't put that much time into just yet.

Under the covers, nCoffeeScript uses Mozilla's Rhino. nCoffeeScript interfaces with Rhino using IKVM for Java/.NET interoperability. nCoffeeScript is inspired by jCoffeeScript in its use of Rhino to execute the compilation process in Javascript.

Right now, you can use nCoffeeScript to compile an individual CoffeeScript file; you can also pass it a directory, and nCoffeeScript will compile each CoffeeScript file in the directory into its own Javascript file. By default, nCoffeeScript will wrap the compiled Javascript in a safety function. This wrapper can optionally be left out using the "/nowrap" command-line option.

For more details, visit the Github repo! Hopefully this is one step toward making it trivial to leverage CoffeeScript in our web applications. I hope to follow up with a possible path to utilizing nCoffeeScript in ASP.NET builds/deployments.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/905979/untitled.JPG http://posterous.com/users/1kLvJ1zaZjfr Jason Kozemczak cozykozy Jason Kozemczak
Wed, 15 Dec 2010 20:03:00 -0800 Make Your CSS Smarter with Sass http://www.cozykozy.com/make-your-css-smarter-with-sass http://www.cozykozy.com/make-your-css-smarter-with-sass

These days, there is no shortage of "CSS with variables" solutions available to web developers.  Two of the more popular frameworks available today are LESS and Sass.  To be honest, these two options are not all that different (as of v3 of Sass, at least).  Both are supersets of CSS (valid CSS is valid LESS and valid Sass).  Both are Ruby gems, and both share a similar syntax.  Though I'm sure there are subtle differences between the two, I leave it as an exercise for the user to delve into those finer details (maybe you can mention your findings in the comment section?).

I've tended to lean towards Sass; the language is a part of the HAML gem, a templating system that allows developers to write templates in a syntax similar to Ruby.  I've spent a small amount of time with HAML, and that probably explains why I'm partial to Sass. I'll walk you through some of Sass's features and provide a possible solution to leveraging Sass in ASP.NET applications.

Nested Styles

How many times have you written the following?

1
2
3
4
5
6
7
8
9
10
11
12
13
a {
  text-decoration: none;
  color: green;
}
a:hover {
  text-decoration: underline;
}
a:active {
  color: purple;
}
a:visited {
  color: yellow;
}

Granted, my color choices are a bit underwhelming, but that aside, this is certainly not new territory!  With Sass, we can utilize nested styles to better organize our styles.  Combining the power of nested styles and another one of Sass's features, parent references, we can write the same code in Sass as:

1
2
3
4
5
6
7
8
9
10
11
12
a {
  color: green;
  &:hover {
    text-decoration: underline;
  }
  &:active {
    color: purple;
  }
  &:visited {
    color: yellow;
  }
}

In the above example, we've used the & character to reference the parent style element (in this case, anchor elements) Now, as far as total line count, we haven't really saved ourselves much (1 lousy line).  What we have gained, however, is a deeper abstraction of our various elements' styling, which is ultimately what we as developers try to do day in and day out.

Variables

Nesting styles alone offers significant leverage, but combining it with the ability to declare variables adds a level of maintainability currently not possible with regular ol' CSS.  Variables in Sass are prefixed with the $ character; variables can be assigned to text, numbers, etc. Wordpress theme writers could really put Sass to work for them:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$main-color: #701A14;
$sub-color: #A64C32;
$accent-color: #BF8B5B;

/* Changing color schemes is as simple as updating the 3 lines above */
p {
  color: $main-color;
  background-color: $sub-color;
  .accent {
    color: $sub-color;
  }
}

/* ... */

Functions/Operations

Theme creators might be underwhelmed by my previous example, especially since they can do a "Find all and replace" to change colors out; where they might scratch their heads is Sass's built-in functions and math operators.  These abstractions allow for easy color manipulation and layout calculations, all handled within the style sheet.

Mixins

Of all of Sass's features, the one probably most alien to the average person writing CSS is mixins.  For the non-Rubyists out there, mixins is a feature of Ruby that offers a form of inheritance that looks more like composition.  You can read more about it at Pragmatic Programmer's Guide.  In Sass, mixins allow the developer to define small portions of CSS styling which can then be imported into other styles.  An example will make this more clear:

1
2
3
4
5
6
7
8
9
10
11
@mixin colorize {
    $color: blue;
    $bg-color: green;
    color: $color;
    background-color: $bg-color;
}

p {
    @include colorize;
    margin-bottom: 20px;
}

When the Sass styles are "compiled" down to regular ol' CSS, the above looks something like this:

1
2
3
4
p {
  color: blue;
  background-color: green;
  margin-bottom: 20px; }

... And Much More!

There are a number features available in Sass that I haven't touched on, including the ability to import other Sass stylesheets, as well as the ability to pass arguments to your mixins.  If you'd like to learn more about Sass, I'd recommend just visiting the site; it undoubtably does a better job describing what it does and examples that better show its utility.  One of the interesting things I thought would be cool to explore is incorporating Sass into ASP.NET web applications by adding the Sass compilation step to the build process in Visual Studio/MSBuild.  I'll outline the steps to getting this working quickly below.

Sass + ASP.NET

If you're developing an ASP.NET app, you're probably working in Windows, so I'm going to target this walkthrough at Windows folks; if you're doing work in Mono and you'd like instructions on getting this working with Monodevelop or the like, let me know in the comments and I'll see what I can whip up...

Installing Ruby

If you don't already have Ruby installed on your machine, you'll want to install that, as Sass is a Ruby gem.  For a quick and painless install, I'd just go to the RubyInstaller download page, get the newest version (at the time of writing, 1.9.2), and run the installer.

Screen_shot_2010-12-15_at_8

You'll want to make sure you check the checkbox asking if you want to add Ruby to the Path.  Otherwise, it's a bit of a pain to use Sass from command line.

Installing the HAML/Sass gem

Once the Ruby installer has finished, open up a command prompt and enter the following command:

gem install haml

This command tells Ruby Gems, a package manager that allows you to install, update, and keep track of the various Ruby libraries (gems), to install the HAML gem; Sass is a part of the HAML gem, so once that has finished we'll be set as far pre-reqs. As an aside, if your team has a build server, you'll obviously want to get Ruby/Sass installed on the build server so that it can transform the Sass stylesheets into CSS stylesheets when it comes time to build.  In short, you'll probably want to install Ruby/Sass locally on your development machine (if you're doing quick builds to test functionality), as well as the server where the "official" builds are done.

Visual Studio/MSBuild Integration

Now that we've got Sass installed, we can begin to leverage it in our ASP.NET web apps.  Let's start by creating a new web application in Visual Studio:

Screen_shot_2010-12-15_at_8

Create a new folder at the root of the site called "css".  Right-click on that new folder, and choose "Add -> New Item."  Choose "Text File" as the filetype and enter "style.scss" as the filename:

Screen_shot_2010-12-15_at_9
One unfortunate side effect of this is that since we're choosing a filetype of "Text File," we're not going to get any of the pretty syntax highlighting we know and love in VS.  Furthermore, we can't easily associate file extensions with the CSS Editor.  I've seen examples on the web of how to do this, but the other caveat is that the code completion engine gets pretty confused by the nested styles, mixins, etc. of Sass, so it's probably easiest just to leave it be.  If you're really in need of some syntax highlighting, I'd recommend editing the Sass stylesheet outside of VS using Notepad++.

There's a nice command built into Sass that will make Sass watch a file or directory for changes to Sass files and automatically compile them as they are updated.  This could be helpful while coding.  "sass --watch [PATH_TO_STYLE_DIR]" will do this for you.

Using the watch command is helpful, but it won't ensure that your CSS files are always up-to-date, especially if other developers are working on the codebase.  We'll add a post-build event to our project file so that we can ensure our CSS file is always up-to-date when we build and/or deploy.  Right-click on the web application project file in the Solution Explorer and choose "Properties."  In the Properties window, click the "Build Events" tab.  In the post-build event command line textbox, enter the following:

sass "$(ProjectDir)css\*.scss" "$(ProjectDir)css\*.css"

Screen_shot_2010-12-15_at_9

This command will tell Sass to compile all the Sass stylesheets in the "css" folder into CSS files.  This might not be the optimal command if you're utilizing the @import functionality in Sass and don't actually want to compile ALL Sass files in that directory.  Edit this command to meeet your needs.  When you're done, be sure to save.

Before we get on with it, I'm going to add a "style.css" file to the "css" folder.  This is really just going to serve as a placeholder file.  We won't directly edit it, but it will make it easier to deploy/version control the files if we add it anyway.  Right-click on the "css" folder in Solution Explorer and choose "Add -> New Item"; choose the stylesheet filetype and enter "style.css" as the filename.

Now that we're squared away, let's test out what we've done.  Open up the "style.scss" file and enter some Sass:

1
2
3
4
5
6
7
8
9
10
11
12
13
/* style.scss */

@mixin colorize {
    $color: blue;
    $bg-color: green;
    color: $color;
    background-color: $bg-color;
}

p {
    @include colorize;
    margin-bottom: 20px;
}

One of the beauties of hooking Sass into the post-build is that we'll essentially get compile-time validation of our Sass.  If you try to build and get errors, check that Ruby is in the path, that the HAML gem is installed.  Double-check the post-build event command line text; lastly, make sure you Sass is legal!  If you've followed the above, you shouldn't have a problem.

Once we've verified our Sass is building correctly, let's put it to work.  Open the "Default.aspx" file and add a stylesheet link in the document HEAD to the "style.css" file:

<link rel="Stylesheet" type="text/css" href="css/style.css" />

While you're at it, insert a <p> element into the body of the webform and put some text in it.  Launch the debugger and bask in the glory! Feel free to adapt this method to suit your needs; everybody's situation is different!

Sass + ASP.NET FTW

Hopefully this post has piqued your interest in Sass and other CSS frameworks.  I've given some direction on integrating Sass into ASP.NET applications.  Integrating existing applications would be almost as trivial, as valid CSS is of course valid Sass.  Leveraging the abstractions that Sass allows can help to make for more maintable and more concise styling.

I've zipped up the sample web app we created above, you can get it here.  Enjoy!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/905979/untitled.JPG http://posterous.com/users/1kLvJ1zaZjfr Jason Kozemczak cozykozy Jason Kozemczak
Mon, 13 Dec 2010 19:33:00 -0800 More Effective .NET via Effective Java: Static Factories http://www.cozykozy.com/more-effective-net-via-effective-java http://www.cozykozy.com/more-effective-net-via-effective-java

Yesterday, I talked briefly about one of my favorite takeaways from Joshua Bloch's Effective Java: the typesafe enum pattern.  Today I'd like to discuss another one of 57 points Bloch discusses in his book and how it can be understood and implemented from a .NET standpoint; the first point he makes in the book is to consider implementing static factory methods in your classes.

When developers start coding a class, we often start with what seems quite innocent:

1
2
3
4
5
6
7
public class SomeClass
{
  public SomeClass()
  {
    // do something awesome here
  }
}

Now, this is inherently bad, but we lose a certain amount of control over the use of our class when we allow public constructors.  For one, we no longer have control over how many instances of a class we will allow.  This might be important in a situation where we're managing a pool of database connections, for instance.

1
2
3
4
5
6
7
8
public class DBConnection
{
  private const int MAXCONNECTIONS = 5; // arbitrary
  public DBConnection()
  {
    // Oh no, what if we're over the max allowed connections!
  }
}

 Furthermore, if we have enough constructors, we might run into a signature collision, where the only alternative is to rearrange the parameter types of one or more constructors.  This will almost always be a compromise, and probably one that comes with the cost of confusing the consumer of the class.  In short, we're limited by the fact that classes can only have 1 constructor for any given signature:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// this class doesn't compile!
public class DBConnection
{
  public DBConnection(string pConnectionString, bool pIsTransactional)
  {
    // do something mind-blowingly awesome
  }

  public DBConnection(string pConnectionString, bool pKeepAlive)
  {
    // this would do something awesome if the compiler wouldn't complain!
  }

  // ...
}

But alas, we won't let the compiler get the best of us!  We can turn our constructors into public static factory methods:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class DBConnection
{
  private const int MAXCONNECTIONS = 5;
  private static int connectionsOpen = 0;

  private DBConnection(){}

  // static factory in some sort of pooling situation
  public static DBConnection GetConnection()
  {
     while (connectionsOpen >= MAXCONNECTIONS)
        // spin
     
     // now that we've got a connection available, let's up the counter and return it
     connectionsOpen++;
     return new DBConnection();
  }

  public static DBConnection DBConnectionWithConnectionString(string pConnectionString)
  {
    // we'd return a new DBConnection object based on the connection string passed in
  }

  // NOTE: if this and the above were constructors, we'd get a compiler error b/c of the matching signatures!
  public static DBConnection DBConnectionByName(string pName)
  {
     // maybe we have specific named instances? I don't know, but this method is more descriptive than using a constructor
  }

}

A few things to note about the above example.  One, it doesn't really make any sense; I haven't done a good job at making a sensical class, and I apologize for that.  I've basically hodge-podged a few static factory methods into a class to point out the advantages vs. traditional object constructors.

Static Factories Over Constructors?

By using static factory methods, we can better manage instances of our class (if we're concerned about such things), this is highlighted in the top static method.  The beauty of this implementation is that you can adjust the number of allowed instances without the user having to worry about it.  You could even transform the class into a singleton by making adjustments inside the factory method!

The last two static methods are used to highlight the more descriptive nature of static factory methods vs. constructors; it also serves the purpose of showing how signature collissions become essentially a non-issue with static factory methods.  Note that both static factory method's names help to inform the user certain characteristics of the objects they return.  Additionally, they share the same signature, which would not be possible if constructors had been used in their place.

Another advantage that Bloch points out that I haven't demonstrated is that using static factory methods allows you the ability to return instances of subclasses in your static factory methods.  I once wrote a small set of classes that calculated the driving distance between two locations using Google Maps and Bing Maps.  I essentially subclassed the interaction between either group and created a static factory method that returned an instance of one or the other.  Generally, it returned only instances of the Bing Maps-based calculator, but could have been easily "switched" out with the Google Maps-based calculator should Bing's mapping services ever went down.

The Grass is Always Greener

To close, don't let this post misguide you into thinking that factory methods are always superior to constructors.  One of the major limitations is that without public constructors, you are essentially making your class sealed.  This might potentially be bad if you explicitly want your class to be able to be subclassed.  However, note that this implementation doesn't stop users from utilizing your class through composition (in contrast to inheritance), which can sometimes be a "cleaner" way of leveraging a class's behavior.

In addition to the "sealed" byproduct, you also fight the fact that static factory methods don't "look" any different than other static methods in a class (i.e. they aren't differentiated from other methods like constructors are).  This could frustrate users of your classes if you aren't descriptive in your class's public contract.  Again, use judgement and pragmatism when deciding on implemeting constructors of static factory methods (or maybe use both!).

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/905979/untitled.JPG http://posterous.com/users/1kLvJ1zaZjfr Jason Kozemczak cozykozy Jason Kozemczak
Sun, 12 Dec 2010 20:42:00 -0800 Effective .NET via Effective Java: Typesafe Enums http://www.cozykozy.com/effective-net-via-effective-java http://www.cozykozy.com/effective-net-via-effective-java

A few weeks ago I bore through Joshua Bloch's Effective Java.  I'd heard a number of good things about the text, and even though I code professionally in .NET these days, good OO practice is good OO practice regardless of the language.

Bloch's book is laid out in the same fashion as the classic Effective C++ (Scott Meyers); Bloch lays out 57 suggestions to writing "better" Java code.  One of the ones that gave me an "A ha" moment was Item #21, which presents the "typesafe enum" pattern.  Bloch's examples are of course in Java, but the pattern can be utilized in .NET (and probably a number of other languages, though I'll focus on .NET in this post).

Bloch proposes that more often than not, Enums can (and should) be replaced by class behavior.  I'll present an example to illustrate the advantages to this methodology.

Let's assume we're implementing a card game in .NET.  We'd quickly find the need to enumerate the various suits of cards.  It'd probably look something like this

1
2
3
4
5
6
7
public Enum Suit
{
  Spades,
  Clubs,
  Diamonds,
  Hearts
}

This would probably work well enough, but this doesn't really get us very far.  Enums can't implement methods, inherit interfaces, etc.  They're a little bit more than named integer constants  We can pretty easily get this sort of functionality plus a quite a bit more with just a bit more work.  Now, consider the following class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Suit
{
  public static readonly Suit CLUBS = new Suit("Hearts");
  public static readonly Suit DIAMONDS = new Suit("Diamonds");
  public static readonly Suit HEARTS = new Suit("Hearts");
  public static readonly Suit SPADES = new Suit("Spades");

  private Suit(string pName)
  {
    name = pName;
  }

  private string name;
  public string Name
  {
    get { return name; }
  }
}

What we do by making the constructor private is limit the instantiated instances to only the 4 public facing static instances, which each represent the four suits.  We can now access those instances in a similar fashion to how we access Enum values: Suit.CLUBS, Suit.DIAMONDS, etc.

Now, the above example is somewhat trivial, but where the power lies is that we are now working with dyed-in-the wool classes, so we can add all the instance methods and properties we can dream up.  One of the great bonuses is that since we know there will only be four instances of this class, object equality "just works" since we know that all references to instances of the Suit class will relate back to one of the public-facing four.

We can go even further: since our Suits are now just instances of a class, we can make the Suit class implement any interface we choose, and we can gain the benefits to that implementation (IComparable comes to mind).

One of the other issues Bloch delves in on is the issues around Serialization.  If you are de-serializing instances of the Suit class, this will introduce additional instances of the Suit class; though I'm not going to dive into the details, it's possible to also overcome issues revolving around that.

I can imagine a number of applications where a typesafe enum class makes more sense than the traditional Enum.  That said, each situation is different, and certainly there are situations where this pattern doesn't offer any sizable advantages.  Can you think of a time when you used an Enum where the typesafe enum pattern made more sense?  Maybe I haven't done enough to convince you of the power behind this pattern?  Let me know in the comments!  I might follow up with a more "real world" example where this pattern can be leveraged!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/905979/untitled.JPG http://posterous.com/users/1kLvJ1zaZjfr Jason Kozemczak cozykozy Jason Kozemczak