Adapter pattern in practice by swift

Amr Al-khayat
Dev Genius
Published in
4 min readFeb 5, 2022

--

The adapter pattern is one of the structural design patterns, and it allows us to adapt the interface of the component to the interface the client expects without changing the component.

For example, if you bought an iPhone from USA and traveled to the UK you will need an adapter to be able to charge your iPhone. In this situation, the Client is the iPhone.

Adapter design pattern diagram

Client: the object that uses an adapter.

NewProtocol: since swift does not support multiple inheritances we are using the protocol.

Adapter: conform to the New protocol, and passes onto the legacy object.

Adaptee(Legacy objects): this is code can not be modified like third-party libraries.

Enough talk about theoretical definition 🙁 let’s dive into a real couple of examples.

  • We want to use multiple Authentications implementation in applications like Google, Facebook or our own authentication. A good choice to use an adapter pattern in this situation, why? Because if we want to use Google and Facebook authentication in the application, and separate the implementation for each one into the individual adapters, and we have only one protocol all adapters conform to this protocol in this situation we decoupled our client from legacy code which means we can test our business logic isolated, and freedom to add or remove any authentications without breaking our Code.
  • We want our application to support caching using, for example, Core data or Realm in this situation it is a good choice to use an adapter. Why? imagined you have used Realm without using an adapter, and after that, we decide to use Core data instead what is going to happen in this situation you should modify all application code is not practiced way. what If we have used an adapter we separated realm implementation from Client. You have the freedom to remove Realm or add Core data implementation without breaking legacy code or Tests.

The adapter has a lot of uses and a powerful pattern for decoupling code.

Authentication Example

Without use Adapter Pattern

In this example, I have implemented Sign in with Google if would you like to read more about googleSignIn. Now you are seeing this is code clean, but loginViewController is tightly coupled with google SignIn third party library imagined you added a new dependency like Facebook SignIn or Login with Apple you will increase dependencies in LoginViewController in this situation is hard to test your code because is tightly coupled, and what if you add or remove any dependencies it will take time😩😩😩.

Let’s implement adapter pattern for this problem 🥳🥳

1- Create abstraction protocol ‘Authentications’, and add one method signIn. At this point, we can test the behavior of signIn method without dependence on any third-party library.

New Protocol

2- Create ‘User’ model. I have chosen those properties you can add whatever you want.🤗

User Model

3- Create a new class ‘GoogleSignInAuthenticatorAdapter’, and confirm to Authentications to be able to implement SigIn method we have isolated GoogleSignIn implementation(legacy code) from ‘LoginViewController’ take this responsibility to Adapter.

Adapter

4- Create a new property ‘authService’ typed as Authentications protocol, and initialize ‘GoogleSignInAuthenticatorAdapter’ in the ‘viewDidLoad’, and then declare button ‘SignInWithGoogleBtn’ to be able to implement ‘signIn’.

Now LoginViewController is decoupled from Google SignIn , and we have freedom to change google signIn with any dependency without breaking existing code😊.

Client

If you would like to see the source code https://github.com/amralkhayat/AdpaterPatternInPractice

--

--