Articles, podcasts and news about Swift development, by John Sundell.

Introducing the BEHEMOTH architectural pattern

Published on 01 Apr 2019

⚠️ In case you find this article now that it’s past the 1st of April: This whole article is an April Fools’ joke and is not intended to be taken seriously. You can find lots of real articles and podcast episodes about architecture here.

We all know that the most interesting thing to discuss when it comes to building apps is what design pattern that we’ll use. After all, sticking to a strict pattern is much more important than pragmatism, and — in general — the more letters a design pattern abbreviation has, the better it usually is.

After years of research and development, studying thousands of apps and their architecture — I’m now super excited to introduce the ultimate way of building iOS apps — the BEHEMOTH architectural design pattern.

Building a BEHEMOTH app is simple. It follows the idea that more layers of abstraction is better, since that makes the architecture more CLEAN (in fact, BEHEMOTH is so clean that it makes Clean Architecture look dirty). Each feature within a BEHEMOTH app is divided into eight layers:

To show you just how simple, clean, and powerful BEHEMOTH is — let’s dive in and build an app using it. Let’s say that we’re building a calendar app, and that we need to construct a sub-system to perform various date-related operations. To get started, let’s create our Backend — which will act as the root layer of our app, providing us with the current system date:

class DateBackend {
    func makeDate() -> Date {
        return Date()
    }
}

The beauty of BEHEMOTH’s design is that every layer is wrapped into yet another layer — sort of like a delicious birthday cake. So before we can use our above backend, we need to wrap it inside an Encapsulation, which provides a much cleaner (and more testable!) interface to the rest of the app:

class DateEncapsulation {
    private let backend: DateBackend

    init(backend: DateBackend) {
        self.backend = backend
    }

    func provideDate() -> Date {
        return backend.makeDate()
    }
}

OK, two layers down, six to go. Next, we need a way to actually handle the date that was provided by our encapsulation, so let’s add our Handler — which will perform its handling by returning a DateErrorChecker:

class DateHandler {
    private let encapsulation: DateEncapsulation

    init(encapsulation: DateEncapsulation) {
        self.encapsulation = encapsulation
    }

    func handle(_ date: Date) -> DateErrorChecker {
        return DateErrorChecker(date: date)
    }
}

The role of an Error checker is to make sure that the handler’s value didn’t produce any errors. It doesn’t really matter whether or not the value can produce errors — if that’s the case then we’ll just make something up in order to satisfy our BEHEMOTH structure — for example here we’re checking that the date passed isn’t in the distant future:

class DateErrorChecker {
    private let date: Date

    init(date: Date) {
        self.date = date
    }

    func check() -> DateModel? {
        guard date != Date.distantFuture else {
            print("This app is outdated")
            return nil
        }

        return DateModel(date: date)
    }
}

As you can see above, the recommended way to propagate errors in a BEHEMOTH app is to simply print them. That way we don’t need to bother the user with code-level details — and by silently failing we can pretend that everything works as it should, in order to avoid negative reviews on the App Store.

OK, we’re at the half-way point. So far so good, right? Let’s take a look at our Model, which will get injected with the Date produced by the previous layers, and offers a way to produce a DateObserver by calling an observe() method:

class DateModel {
    private var date: Date
    private var observers = [(Date) -> Void]()

    init(date: Date) {
        self.date = date
    }

    func observe() -> DateObserver {
        let observer = DateObserver(date: date)
        observers.append { observer.date = $0 }
        return observer
    }
}

In a BEHEMOTH app, an Observer is simply an object that contains a piece of data, that the model can then update. So for our calendar app, all we have to do is to create a simple class with a Date property:

class DateObserver {
    var date: Date

    init(date: Date) {
        self.date = date
    }
}

Only two more layers to go! Using the above observer, let’s set up our Transformer, which will transform a Date instance into the data that we actually need. For example, here we’re transforming the observer’s date into a Bool that indicates whether the current date is April 1st:

class DateTransformer {
    var isAprilFoolsDay: Bool {
        let calendar = Calendar.current
        let month = calendar.component(.month, from: observer.date)
        let day = calendar.component(.day, from: observer.date)
        return month == 4 && day == 1
    }

    private let observer: DateObserver

    init(observer: DateObserver) {
        self.observer = observer
    }
}

Finally, it’s time to display our data using a Human Interface implementation, which will use the above transformer in order to optionally set the text of a UILabel:

class DateHumanInterface {
    private let label = UILabel()

    func add(to view: UIView) {
        view.addSubview(label)
    }

    func update(with transformer: DateTransformer) {
        if transformer.isAprilFoolsDay {
            label.text = "HAPPY APRIL FOOLS' DAY!"
        }
    }
}

And with that, we’re done! Now all we have to do is to beautifully compose all of the above eight layers into one super clean application:

let backend = DateBackend()
let encapsulation = DateEncapsulation(backend: backend)
let handler = DateHandler(encapsulation: encapsulation)
let errorChecker = handler.handle(encapsulation.provideDate())
let model = errorChecker.check()
let observer = model?.observe()
let transformer = observer.map(DateTransformer.init)
let humanInterface = DateHumanInterface()

humanInterface.add(to: view)
transformer.map(humanInterface.update)

Isn’t that nice? I hope that with this article I’ve convinced you that BEHEMOTH is really the only truly great architectural design pattern for iOS apps, and one that I recommend that all developers should switch to immediately. Its eight distinct layers, each cleanly separated from one another, really provides the rigid structure that we need to build truly great apps — and for our code to become much more testable and easier to maintain.

Later this year, I’ll be launching a book, several conference talks, a video series, and an entire new website (look out for BEHEMOTH by Sundell) — all dedicated to spreading the word about BEHEMOTH and how amazing it is. So stay tuned for that!

Thanks for reading! 🚀


This article is an April Fools’ joke. If you want to read my latest real article, then check out yesterday’s “Bindable values in Swift”. 🙂