The Facade Pattern
Today we’ll investigate the Facade Pattern.
When we have many APIs, we can use the Facade Pattern to represent these as a single, united API.
I’ll illustrate with an example.
Say we have three distinct data sources for customer data:
- A SQL Database holding customer details, and
- A CRM system with API contains the customer addresses,
- A SalesForce REST API provides access to customer orders.
The technologies are unimportant—I only mention them to show that we can use a Facade to combine data from disparate implementations. And the Facade will hide this detail from its clients—a helpful property, as it allows us to change data retrieval technologies under the hood.
Here is the code for the Facade, CustomerRepository
:
public class CustomerRepository : ICustomerRepository { private ICustomerDetailRepository DetailRepo { get; set; } private ICustomerAddressRepository AddressRepo { get; set; } private ICustomerOrderRepository OrderRepo { get; set; } public CustomerRepository(ICustomerDetailRepository detailRepo, ICustomerAddressRepository addressRepo, ICustomerOrderRepository orderRepo) { DetailRepo = detailRepo; AddressRepo = addressRepo; OrderRepo = orderRepo; } public Customer Get(string customerNumber) { var detail = DetailRepo.Get(customerNumber); var address = AddressRepo.Get(customerNumber); var orders = OrderRepo.Get(customerNumber); return new Customer(detail, address, orders); } }
When we call CustomerRepository.Get(customerNumber)
, we delegate the task of retrieving the complete customer data to the underlying Detail, Address and Order APIs. We then combine their results into a new Customer
object return value. Consequently, any high-level business logic calling CustomerRepository.Get()
would be unaware, as it should be, of the piecemeal data retrieval from several data sources.
The Facade pattern is great for hiding complexity in systems behind a simpler interface. Furthermore, Facade allows the decoupling between abstractions and implementations. If, in our customer retrieval example, we had used the concrete repository classes, then a Facade could be employed to restore the missing abstraction:
public class CustomerRepository : ICustomerRepository { private SqlCustomerDetailRepository DetailRepo { get; set; } private CrmCustomerAddressRepository AddressRepo { get; set; } private SalesForceCustomerOrderRepository OrderRepo { get; set; } public CustomerRepository() { // Not shown: Initialisation of concrete data retrieval instances. DetailRepo = new SqlCustomerDetailRepository(config); AddressRepo = new CrmCustomerAddressRepository(config); OrderRepo = new SalesForceCustomerOrderRepository(config); } public Customer Get(string customerNumber) { var detail = DetailRepo.Get(customerNumber); var address = AddressRepo.Get(customerNumber); var orders = OrderRepo.Get(customerNumber); return new Customer(detail, address, orders); } }
In summary, the Facade pattern is about making multiple APIs appear as one. It is a practical and frequently used pattern.
Leave a Reply
Want to join the discussion?Feel free to contribute!