What are facades and how to use it on ruby

Cherry Ramatis - Jun 15 '23 - - Dev Community

To understand the usage of facades on real-life projects, let's imagine that we'll implement an integration with a third-party SDK like Stripe to allow payments on our system. All cool, right?

Ok but... What is the problem with this?

Since we need to implement this SDK, the first thing that we can think of is to install the gem and just use it on our controller methods, right? Let's imagine that this gem provides the following class:

class AwesomeStripeSDK
  def identify_user; end
  def register_card_for_user; end
  def pay; end
  def refund; end
  def apply_discount; end
  def cancel_payment; end
  def call_the_cops; end
  ....
end
Enter fullscreen mode Exit fullscreen mode

Can we agree that this is a big class with an unknown number of parameters, right?

Although it's easy to just read the docs and implement the correct methods with the correct parameters on our controller, it can become a little monster pretty easily, simply because we don't have much control over this whole AwesomeStripeSDK class.

This gem could provide multiple classes that need to be used together for a single action or even provide a very confusing and messy set of method names, parameter structures, etc.

The solution ? Facades!

Now that we understand the problem, it's pretty simple to propose a solution: just create another class!

The idea behind a facade is to simplify the implementation of a library or framework and also control the general structure of this service class.

For example, given the example AwesomeStripeSDK third party class, we can define a facade like the following:

class PaymentFacade
  def self.pay(price:, card:, user:)
    # identify our user
    AwesomeStripeSDK.identify(user)

    # register the payment method
    AwesomeStripeSDK.register_card_for_user(user, card)

    # apply a fixed discount
    AwesomeStripeSDK.apply_discount(40)

    # pay the bill
    AwesomeStripeSDK.pay(price)
  end
end
Enter fullscreen mode Exit fullscreen mode

Now on our controller, we just need to call the PaymentFacade.pay passing the correct parameters, and we can ensure that the payment is going to be made correctly without worrying about the specific SDK API.

Another obvious advantage of this is that we can use the same facade on multiple classes in separate contexts and also write great tests since the scope is isolated. Cool, right?

. . . . . . . . . . . . . . . . . . . . . .