Facade design pattern - Structural
Pradip Shinde
Software Architect | Transformation | Scalable Apps | Microservices | .Net 8
Definition -
Provides an unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use. Isolates your code from the complexity of a subsystem.
Problem statement –
Check customers eligibility to apply for loan.
System has to communicate with different sub systems/components individually and based on that eligibility is checked
Solution -
Create a facade(Mortgage) class by having IsEligible(Customer obj) method which will be responsible to communicate with sub systems/ classes/ modules. This solution will simplify the Client to use unified single communication and abstract the logic inside Mortgage class.
Code snippet -
/// <summary> /// The 'Subsystem Bank' class /// </summary> class Bank { public bool HasSufficientSavings(Customer c, int amount) { Console.WriteLine("Check bank for " + c.Name); return true; } } /// <summary> /// The 'Subsystem Credit' class /// </summary> class Credit { public bool HasGoodCredit(Customer c) { Console.WriteLine("Check credit for " + c.Name); return true; } } /// <summary> /// The 'Subsystem Loan' class /// </summary> class Loan { public bool HasNoBadLoans(Customer c) { Console.WriteLine("Check loans for " + c.Name); return true; } } /// <summary> /// Customer class /// </summary> class Customer { private string _name; // Constructor public Customer(string name) { this._name = name; } // Gets the name public string Name { get { return _name; } } } /// <summary> /// The 'Facade' class /// </summary> class Mortgage { private Bank _bank = new Bank(); private Loan _loan = new Loan(); private Credit _credit = new Credit(); public bool IsEligible(Customer cust, int amount) { Console.WriteLine("{0} applies for {1:C} loan\n", cust.Name, amount); bool eligible = true; // Check creditworthyness of applicant if (!_bank.HasSufficientSavings(cust, amount)) { eligible = false; } else if (!_loan.HasNoBadLoans(cust)) { eligible = false; } else if (!_credit.HasGoodCredit(cust)) { eligible = false; } return eligible; } } class Program { static void Main(string[] args) { // Facade Mortgage mortgage = new Mortgage(); // Evaluate mortgage eligibility for customer Customer customer = new Customer("Ann McKinsey"); bool eligible = mortgage.IsEligible(customer, 125000); Console.WriteLine("\n" + customer.Name + " has been " + (eligible ? "Approved" : "Rejected")); // Wait for user Console.ReadKey(); } }
Relationships with other patterns –
- Facade defines a new interface for existing objects, whereas Adapter tries to make the existing interface usable. Adapter usually wraps just one object, while Facade works with an entire subsystem of objects.
- Abstract Factory can serve as an alternative to Facade when you only want to hide the way the subsystem objects are created from the client code.
- Facade and Mediator have similar jobs: they try to organize collaboration between lots of tightly coupled classes.
- A Facade class can often be transformed into a Singleton since a single facade object is sufficient in most cases.
- Facade is similar to Proxy in that both buffer a complex entity and initialize it on its own. Unlike Facade, Proxy has the same interface as its service object, which makes them interchangeable.
Currently working as a Specialist Software Enginnering on Banking Domain Privacy applications.
4 年Very nice article.