Facade Pattern

Problem: Imagine that you must make your code work with a broad set of objects that belong to a sophisticated library or framework. Ordinarily, you’d need to initialize all of those objects, keep track of dependencies, execute methods in the correct order, and so on.

As a result, the business logic of your classes would become tightly coupled to the implementation details of 3rd-party classes, making it hard to comprehend and maintain.

Facade provides a unified or a single-point interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use. This subsystem can be a library, a framework, or any other complex set of classes.

A real-world example is implementing Stripe as a Payment Gateway into your system. At first, you will need a couple of classes from Stripe to get started like Customer, Plan, Card, BankAccount, Subscription, etc. Then they have their own interfaces. As you can see, the number of interfaces you need to deal with can be a lot. You will then be concerned about decoupling Stripe from the rest of your application so that if you decide one day that Stripe is not for you that you can easily switch to Braintree or something else. Having a facade as a single point of interaction is very helpful. You can switch from StripeFacade to a BrainTreeFacade or something like that.

Applicability

1. Use the Facade pattern when you need to have a limited but straightforward interface to a complex subsystem.

2. Often, subsystems get more complex over time. Even applying design patterns typically leads to creating more classes. A subsystem may become more flexible and easier to reuse in various contexts, but the amount of configuration and boilerplate code it demands from a client grows ever larger. The Facade attempts to fix this problem by providing a shortcut to the most-used features of the subsystem which fit most client requirements.

Facade design pattern

3. Use the Facade when you want to structure a subsystem into layers.

4. Create facades to define entry points to each level of a subsystem. You can reduce coupling between multiple subsystems by requiring them to communicate only through facades.

Here is the example with Stripe.

public interface FacadeService {

	Account createAccount(String username, String email, String password);
	
	
	Account addPaymentMethod(Account account, PaymentMethod paymentMethod);
	
	
	Payment makePayment(PaymentMethod paymentMethod, double amount);
}
public class FacadeServiceImp implements FacadeService {

	private AccountService accountService;
	private PaymentMethodService paymentMethodService;
	private PaymentService paymentService;

	// there can more services here.
	private SubscriptionService subscriptionService;
	private EmailService emailService;

	public FacadeServiceImp() {
		super();
		accountService = new AccountService();
		paymentMethodService = new PaymentMethodService();
		paymentService = new PaymentService();

	}

	@Override
	public Account createAccount(String username, String email, String password) {
		// TODO Auto-generated method stub
		return accountService.create(username, email, password);
	}

	@Override
	public Account addPaymentMethod(Account account, PaymentMethod paymentMethod) {
		// TODO Auto-generated method stub
		return paymentMethodService.add(account, paymentMethod);
	}

	@Override
	public Payment makePayment(PaymentMethod paymentMethod, double amount) {
		// TODO Auto-generated method stub
		return paymentService.charge(paymentMethod, amount);
	}

}

public class FacadeDemo {

	public static void main(String[] args) {

		FacadeService facadeService = new FacadeServiceImp();

		String username = "folauk";
		String email = "folaudev@gmail.com";		
		String password = "Test1234!";
		
		Account account = facadeService.createAccount(username, email, password);
		
		PaymentMethod paymentMethod = new PaymentMethod();
		paymentMethod.setAccount(account);
		paymentMethod.setName("Laulau");
		paymentMethod.setLast4("4242");
		
		account = facadeService.addPaymentMethod(account, paymentMethod);
		
		double chargeAmount = 100;
		
		Payment payment = facadeService.makePayment(paymentMethod, chargeAmount);
	}
}




Subscribe To Our Newsletter
You will receive our latest post and tutorial.
Thank you for subscribing!

required
required


Leave a Reply

Your email address will not be published. Required fields are marked *