Although maybe not well known, class cluster is a widely used design pattern in the Cocoa framework. Class cluster uses a uniform and unique public class to define an interface, while replies on several private classes for detail implementation under the hood. The most advantage we could take from this is avoiding the complexity which multiple similar public classes could bring. A typical example of class cluster is NSNumber: We have a series of methods to create an NSNumber object from an integer, float or bool value. But in fact they belong to different private subclass:

NSNumber * num1 = [[NSNumber alloc] initWithInt:1];
// __NSCFNumber

NSNumber * num2 = [[NSNumber alloc] initWithFloat:1.0];
// __NSCFNumber

NSNumber * num3 = [[NSNumber alloc] initWithBool:YES];
// __NSCFBoolean

Class cluster is extremely useful when you have quite a few subclasses, but all of them follow a similar pattern. Your interface could be simplified so users of your code are able to ignore your implementation detail.

In Objective-C, the init methods do very similar things with other normal methods. Since that, class clusters are implemented without any difficulty in Objective-C. You just replace the self in init method, and return proper subclass object based on the input type.

However, things become different in Swift. The init methods in Swift are real initiating methods. We can only get an object of that class when we call init, instead of getting an object of subclass. That means we cannot rely on the init method to construct a class cluster. To build class cluster in Swift, an effective way is using the factory pattern. The factory method of Drinking below create a class cluster for two private class Coke and Beer:

class Drinking {
    typealias LiquidColor = UIColor
    var color: LiquidColor {
        return LiquidColor.clearColor()

    class func drinking(name: String) -> Drinking {
        var drinking: Drinking
        switch name {
        case "Coke":
            drinking = Coke()
        case "Beer":
            drinking = Beer()
            drinking = Drinking()

        return drinking

class Coke: Drinking {
    override var color: LiquidColor {
        return LiquidColor.blackColor()

class Beer: Drinking {
    override var color: LiquidColor {
        return LiquidColor.yellowColor()

let coke = Drinking.drinking("Coke")
coke.color // Black

let beer = Drinking.drinking("Beer")
beer.color // Yellow

By using the trick mentioned in Get type of instance, we can confirm that coke and beer is an object of Coke and Beer respectively.

let cokeClass = NSStringFromClass(coke.dynamicType) //Coke
let beerClass = NSStringFromClass(beer.dynamicType) //Beer