Search code examples
design-patternsdependency-injectionfacade

In what scenario, you will choose Facade pattern and DI?


Please tell the real time scenario of Facade pattern and DI. Can I replace DI with Facade Pattern.


Solution

  • The Facade pattern is used to simplify interactions with (potentially) complex subsystems.

    A real world example might be something like a PaymentFacade in a banking system.

    For this example, as a developer, you want a simple interface that you can invoke to make payments - i.e. you just give it an account number to pay from, and account number to pay to, and a payment amount and it processes a payment. However, the actual process that happens behind the scenes is much more complicated and it involves various subsystems and legacy components. First, it needs to check if the account is valid, then it needs to check if the account balance is sufficient to cover the payment, it has to instruct the payment processing system to process it, etc.

    So the actual code behind processing a payment could look like this:

    accountService.validateAccountNumber(toAccount);
    int balance = accountService.getBalance(fromAccount);
    
    if (balance < paymentAmount) {
        raiseError("Insufficient funds");
    }
    
    paymentService.processPayment(fromAccount, toAccount, paymentAmount)
    

    The first option you have is to replicate this code all over the system, and hope that every developer who writes payment processing code remembers to hit all the relevant subsystems. Alternatively, you can create a PaymentFacade that encapsulates all of this logic and hides the complexity behind it - so you can just call a single method on the facade to process payments.

    paymentFacade.processPayment(fromAccount, toAccount, paymentAmount);
    

    Dependency inversion, on the other hand, is different from the Facade pattern and you can't compare the two or use one as a substitute for the other.

    Dependency inversion assists in decoupling software modules. You can, however, use dependency inversion in your code that uses the Facade pattern. Instead of explicitly defining which particular facade implementation to use, you can delegate the responsibility for that to something sitting at a higher level - with a framework like Spring, you can specify the details of which facade should be used in your application's config - so if you ever decide to switch to a new way of processing payments, you're code doesn't have to change - the particular facade implementation that it uses will just be swapped out with something else, without your code being affected by the change.