Skip to main content

Command Palette

Search for a command to run...

Swift: Facade Pattern

Published
5 min read

In this article, we are going to see about one of the most used structural design patterns called Facade Pattern. Sometimes, when using the complex system, You would have come across a scenario where you would be instantiating and providing the interaction required for multiple components. At that moment, you would have thought there could be a separate helper class/method which takes the required parameters and performs the operation. Don't worry, this is where the Facade pattern comes into play.

Facade Pattern is used when the consumer doesn't want to know about how the system comprising of multiple components interact. The user need not instantiate each component and know about interaction with other components. We can just provide a simple facade method that performs the operation and takes care of the creation and interaction of other components. Let's see it in action below.

We are considering a scenario of sending an Email here. For example purpose, we had kept the implementation simple. In order to send an Email, you would first need to connect, followed by authentication, send the email and then disconnect from the Email Service.

Here, we had created a class for Connection, which creates the connection when it's initialized. It also provides a method to disconnect, so that you can disconnect once the email is sent.

// Connection.swift
class Connection {
  public init() {
    print("Creates the connection")
  }

  func disconnect() { 
    print("Disconnects the connection")
  }
}

Next, we are creating a data model struct for Email representation which comprises multiple properties. For simplicity purpose, we had kept it to receiverMail, subject and body.

// Email.swift
struct Email {
  let receiverMail: String
  let subject: String
  let body: String
}

After that, we are going to create an EmailService class, which would help us to connect, authenticate and send the email.

// EmailSender.swift
class EmailService {
    // 1
    func connect() -> Connection {
      return Connection()
    }

    // 2
    func authenticate(key: String, secret: String) -> String {
      print("Gets the Auth Token")
      return "Auth Token"
    }

    // 3
    func send(authToken: String, withParameters email: Email) {
     //Sends Email with the parameters and authToken
      print("Sending an Email")
   }
}
  1. connect method creates the instance of Connection class and then returns it. So, that we could use it to disconnect later.
  2. authenticate method evaluates the key, secret to provide an auth token, which would be used to send the Email.
  3. send method gets the authToken and the email parameters then proceeds with its purpose of sending the Email.

Next for simplicity purpose, I had created a ViewController that sends the Email when the view starts loading(viewDidLoad) for the first time.

//ViewController.swift

class ViewController: UIViewController {
  //...

  override func viewDidLoad() {
    super.viewDidLoad()
    // 1
    let emailService = EmailService()
    // 2
    let connection = emailService.connect()
    // 3
    let authToken = emailService.authenticate(key: "Key", secret: "secret")
    // 4
    let email = Email(receiverMail: "abc@xyz.com", subject: "Facade Subject", body: "Facade Body")
    // 5
    emailService.send(authToken: authToken, withParameters: email)
    // 6
    connection.disconnect()
  }
}

// USAGE:
let viewController = ViewController()
viewController.loadViewIfNeeded()
  1. Instance of EmailService is created.
  2. Using the EmailService we are creating the connection using the connect method, which would return the created Connection.
  3. With the help of EmailService, authToken is created using the method authenticate by providing the key and the secret.
  4. The data model struct for sending the Email is created by providing receiverMail, subject and body.
  5. EmailService send method is invoked by providing the created authToken from Step 3 and email Parameters from Step 4, which will send the mail
  6. Using the Connection created in Step 1, we are calling the disconnect method. As the connection is no longer required.

As you could see from the above there are around 6 steps to send an email and we need to understand the creation & interaction between components. It is a good candidate to implement the facade pattern.

Next, we are creating a new class called EmailFacade, the Facade suffix in the class is not mandatory. Here's the code for it.

// EmailFacade.swift
class EmailFacade {
  func send(receiverMail: String, subject: String, body: String) {
    let emailService = EmailService()
    let connection = emailService.connect()
    let authToken = emailService.authenticate(key: "Key", secret: "secret")
    let email = Email(receiverMail: receiverMail, subject: subject, body: body)
    emailService.send(authToken: authToken, withParameters: email)
    connection.disconnect()
  }
}

EmailFacade contains the send method that requires receiverMail, subject and body in order to be called. The send method with the mentioned parameters will take care of the whole process of connecting, authenticating, sending Email and disconnecting. This allows us to send the Email by passing the parameters wherever required without going through all the creation and interaction between components.

This is how our code looks in the ViewController now.

//ViewController.swift

class ViewController: UIViewController {
  //...

  override func viewDidLoad() {
    super.viewDidLoad()
    EmailFacade().send(receiverMail: "abc@xyz.com", subject: "Facade Subject", body: "Facade Body")
  }
}


// USAGE:
let viewController = ViewController()
viewController.loadViewIfNeeded()

An instance of EmailFacade is created and then send method is invoked by passing the required parameters. As you can see, the send method takes care of the whole process of connecting, authenticating, sending Email and disconnecting. You can use this single line of code and send the Email from anywhere.

Facade Pattern provides a simple method for a complex system. In the above case, the simple method(send) allows the consumer to use the facade without knowing or interacting with the other components in the system(connect, authenticate, send Email & disconnect). The Facade has a dependency on all the components used by it. If any components are not used in a facade containing multiple methods, It is better to separate it into multiple facades instead of a single facade comprising of unused components and methods.

Well, That's a wrap for this article. Hope you enjoyed reading it.

Happy Coding!!!