Today we will talk about abstract factory pattern. It handles a little more complex use case. As we know, the sedan family has different models like compact, mid-size and full-size.SUV has same categories. Let’s assume we have two factories. One is focused on compact types and the other is on full size. As the following figure tells us, factory A produces compact sedan and compact SUV. Factory B produces full-size sedan and SUV.

AbstractFactory

Let’s start coding. Here is different sizes of sedans and SUVs. They all conform to respective abstract interface.

protocol Sedan {
    func drive()
}

class CompactSedan: Sedan {
    func drive() {
        print("drive a compact sedan")
    }
}

class MidSizeSedan: Sedan {
    func drive() {
        print("drive a mid-size sedan")
    }
}

class FullSizeSedan: Sedan {
    func drive() {
        print("drive a full-size sedan")
    }
}
protocol SUV {
    func drive()
}

class CompactSUV: SUV {
    func drive() {
        print("drive a compact SUV")
    }
}

class MidSizeSUV: SUV {
    func drive() {
        print("drive a mid-size SUV")
    }
}

class FullSizeSUV: SUV {
    func drive() {
        print("drive a full-size SUV")
    }
}

Then the following is our factories. They all can produce sedan and SUV. A is for compact and B is for full-size.

protocol Factory {
    func produceSedan() -> Sedan
    func produceSUV() -> SUV
}

class FactoryA: Factory {
    func produceSedan() -> Sedan{
        return CompactSedan()
    }

    func produceSUV() -> SUV {
        return CompactSUV()
    }
}

class FactoryB: Factory {
    func produceSedan() -> Sedan {
        return FullSizeSedan()
    }

    func produceSUV() -> SUV {
        return FullSizeSUV()
    }
}

Ok, let’s produce sedan and SUV now.

let factoryA = FactoryA()
let compactSedan = factoryA.produceSedan()
let compactSUV = factoryA.produceSUV()
compactSedan.drive()
compactSUV.drive()

let factoryB = FactoryB()
let fullsizeSedan = factoryB.produceSedan()
let fullsizeSUV = factoryB.produceSUV()
fullsizeSedan.drive()
fullsizeSUV.drive()

Another use case is to make different themes for our UI. There are many elements involved in a theme like label, button, background, etc. But in specific theme, each has a style. Please try abstract factory to build this modal.

If you want to learn other creational patterns, we list them here.

Thanks for your time.