The basic premise is that, not only should an object understand itself and how to operate, abstractly, on data, but it should also understand how to create something which is better suited for the task. It means that the user of the cluster never thinks about it as anything other than one class even though they never actually are working with an instance of that class. In fact, the object that they are using will probably, at some point, be one of two different objects, neither of which are the object that they think it is.
My story of Class Clusters saving my ass:
In a bitmap image editor that I wrote a while back, I was running into a problem with the design: colour space scalability. The program was originally made to only operate on RGB/RGBA images and output RGBA images (it was just to tinker with alpha channels). I came to a point where I wanted to edit an image which was in the white colour space and this program couldn't understand it.
The fundamental aspect of the problem is that these colour spaces have different numbers of colour planes (or pixel channels, if you want to think about a muxed representation) and that operating on them required understanding that the number and meaning of the channels is different. Sure it could be done by wrapping a bunch of cut-and-paste loops in a big case statement or something similar but that seemed too ugly.
Enter Class Clusters:
Instead, I decided to abstract the concept of the actual operations into an object. I then sub-classed the object to allow for colour space dependent implementations which could handle each type of image. After I re-factored all the common code into the super-class, I was left with the subclasses mainly acting to return various constants which would be tedious to track within one object (not to mention being difficult to maintain and understand).
The only remaining work was to create the "temporary" sub-class which would analyze the input image and determine which one of its siblings best understood how to manipulate it. Now, as I want to expand this design, I just add a new subclass and enter a line of code into the temporary object to create instances when they are needed.
The code is small, clean, and simple to understand.
I definitely recommend this to anyone working on a project where the details of model objects should be abstracted. However, it is hard to implement in anything but Objective-C or SmallTalk since they keep the concept of object initialization so general. It can be done in other languages, of course, but you get a lot of simplicity from two-stage object construction.
Back to work,