Facade Design Pattern

Continuing with the Design Patterns Series, this post is about the Facade Design Pattern. Facade is a structural design pattern which provides a unified interface to a set of interfaces in the sub-system. Although this definition is derived from the Gang of Four book, it doesn’t mean that we have to have a set of sub-systems. Later on I’ll try to explain with an example how Facade can be used to improve an existing interface as well. So lets get started.

Problem Statement

For the sake of continuity I’ll use the same example that I had used in the previous post related to State Design Pattern. This time the context will be different and as I have been repeatedly saying during this series on Design Patterns that every time there is a conflict in our mind about which pattern to use, we should see the context of the problem.

Assume we are building software for a bank which deals with Mortgage loans or housing loans. There are various steps which needs to be followed while granting the loan. Assume that you go to a bank and request them for 100000 USD loan, the bank won’t give you all the amount you requested just like that. They’ll follow certain procedures before approving the loan. Even after satisfying all the criteria set by the bank, you might get only fraction of the loan as per the rules and regulations of the bank.

One of the most important step every bank follows before approving the loan is the verification process. At the time of applying the loan you’ll have to submit various documents including your personal details, professional details, financial details etc.Based on these details provided by you the bank will perform the verification and depending on the results will decide to approve or reject your loan application.

Lets say we wish to narrow down our scope a bit and concentrate on only home loans for this blog post. In case of home loans the bank also does verification for the developer or the builder from which you are buying the house to ensure that the developer is a genuine one or not. The bank has a list of preferred builds whose projects are financed by the bank or are pre-approved. But if you are approaching the bank for a project which is not pre-approved or being developed by the preferred developer, that doesn’t mean the bank will simply reject your application. Based on certain conditions, the bank has its own list of blacklisted projects. If the project is blacklisted, then the loan application will be rejected.

Taking these business rules around home loan processing lets start building the software.

Loan Manager without Facade

We have a LoanManager class here which has a Process method. To keep the post simple, assume that the LoanApplication class contains all the details related to the amounts, personal details, professional details etc. For simplicity I’ll not cover these things in this post. Assume that there is some screen or a set of screens which collect all the required details and invoke the Process method which is responsible for approving or rejecting the loan application and informing the applicant about the decision.

    public class LoanManager

    {

        public void Process(LoanApplication application)

        {

            bool personalDetailsAreValid = new PersonalDetailVerifier().VerifyDetails(application);

 

            bool professionalDetailsAreValid = new ProfessionalDetailVerifier().VerifyDetails(application);

 

            bool creditHistoryVerified = new CreditHistoryVerifier().Verify(application);

 

            bool isPreferredDeveloper = new DeveloperVerifier().IsPreferredDeveloper(application.DeveloperName);

 

            bool isProjectApproved = isPreferredDeveloper ? true : new ProjectVerifier().IsBlackListedProject(application.ProjectName);

 

            bool isEligible = personalDetailsAreValid

                && professionalDetailsAreValid

                && creditHistoryVerified

                && isProjectApproved;

 

            application.IsApproved = isEligible;

 

            NotificationService notificationService = new NotificationService();

            notificationService.Notify(application);

        }

    }

Here is the implementation of the Process method. It interacts with various other classes like PersonalDetailVerifier, ProfessionalDetailVerifier, CreditHistoryVerifier, DeveloperVerifier and ProjectVerifier. I have implemented these verifiers as classes. but in real life these will usually be some sort of external services. For example Personal details verification process might involve a phone call to the individual or the person whose details were provided as referral. It could also be done through some Government office based on some unique identity based system. Professional details verification can involve a phone call to the office of the individual or a email communication with the Human Resources department. Credit History verification can involve verification against a central repository of all banks or some other process. And similarly for the developer and the project verification. What I am trying to highlight here is that all these verifiers are basically a distinct systems in their own rights.

Our class LoanManager is tightly coupled with several sub-systems during this process of loan approval. Assume that currently the bank uses a private detective agency for personal and professional verification of the applicant. Due to changes in the regulations the same details can be furnished using a central system developed by the Government. In this scenario we’ll have to modify the LoanManager every time there is some change in the verification system.

Consider another scenario. What if the regulations change and we need to add or modify the existing procedures before approving the loan. In all these scenarios we’ll have to modify the LoanManager class. The example I have shown here is a very simplistic one. More often than not we’ll come across scenarios where we have to make multiple changes. How can we fix this problem.

Refactoring towards Facade Pattern

The Process method depends on the results of the various verifiers. We can follow the commonly suggested method in Gang Of Four book and delegate this responsibility to another object. We can extract the complete verification process into a simplified interface which can aggregate the result of the various sub-systems. In this way our LoanManager class will need to depend upon only one interface and not all the individual sub-systems. Lets look at the refactored code.

    public class LoanManager

    {

        public void Process(LoanApplication application)

        {

            ILoanApplicationVerifier loanApplicationVerifier = new LoanApplicationVerifier();

 

            bool isEligible = loanApplicationVerifier.IsEligible(application);

 

            application.IsApproved = isEligible;

 

            NotificationService notificationService = new NotificationService();

            notificationService.Notify(application);

        }

    }

As you can see, we have abstracted the verification related logic into LoanApplicationVerifier class which implements the interface ILoanApplicationVerifier. The IsEligible method simply returns whether the applicant is eligible or not. By doing so we have made sure that LoanManager need not know exact details about how the verification works. All it needs is the eligibility.

Usage of Facade Pattern within DOTNET Framework

In this example, I have abstracted the verification logic into an interface. It is not always necessary to extract an interface. The Facade pattern can be applied even without having an interface. Look at the objective of the pattern. It is to simplify the sub-system and provide a unified interface. One of the most common example of Facade pattern implementation is the SQLHelper class which was available in the Data Access Application Block provided by the Enterprise Library. It provides a wrapper over ADO.NET. It simplifies the common routine database related activities by providing methods like ExecuteDataSet, ExecuteDataReader etc. You don’t have to worry about the repetitive steps like creating a connection, building a command, executing the command using a data reader.

In my opinion, the complete Enterprise Library itself is a Facade for specific tasks like Logging, Exception Handling, Data Access etc. We use Facade pattern quite regularly without knowing it. For so many years I have been working on applications using layered architecture. The service layer is a big Facade which wraps various underlying services like Authentication, Authorization, Persistence, Logging, Auditing etc. For the end user he or she might be performing a simple action like clicking on the save button, but behind the scenes there are numerous sub-systems which are interacting with one another. In my experience if you are following Model View View Model (MVVM) design pattern or Model View Presenter (MVP) with the model layer being implemented using services and Service Oriented Architecture (SOA), then you are already using Facade pattern.

Conclusion

As we saw from the above examples, Facade pattern helps us to unify various sub-systems and provide a simpler interface. Facade is one of the commonly used design pattern. Sometime we use it even without our knowledge. It is simple to implement. Many a times people get confused between Facade and Adapter design patterns. Based on the class structures they look similar. Once again the intent and the context are useful in deciding which pattern to use. Adapter is used to Adapt an existing interface to a different interface. The Facade pattern provides a new and simplified interface to the existing set of sub systems. The intent in case of Facade is to simply the interaction between various components of the system or application by providing a simpler or unified interface. Adapter makes two incompatible interfaces work together by adapting one to another.

As always the complete working solution is available for download FacadeDesignPatternDemo.zip.

Until next time Happy Programming.

Further Reading

Here are some books I recommend related to the topics discussed in this blog.

Share:
spacer

No comments:

Post a Comment