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.
Solution
A facade is a class that provides a simple interface to a complex subsystem which contains lots of moving parts. A facade might provide limited functionality in comparison to working with the subsystem directly. However, it includes only those features that clients really care about.
Having a facade is handy when you need to integrate your app with a sophisticated library that has dozens of features, but you just need a tiny bit of its functionality.
For instance, an app that uploads short funny videos with cats to social media could potentially use a professional video conversion library. However, all that it really needs is a class with the single method encode(filename, format)
. After creating such a class and connecting it with the video conversion library, you’ll have your first facade.
Structure
Facade Design Pattern Example
MySqlHelper
and OracleHelper
.import java.sql.Connection; public class MySqlHelper { public static Connection getMySqlDBConnection(){ //get MySql DB connection using connection parameters return null; } public void generateMySqlPDFReport(String tableName, Connection con){ //get data from table and generate pdf report } public void generateMySqlHTMLReport(String tableName, Connection con){ //get data from table and generate pdf report } }
import java.sql.Connection; public class OracleHelper { public static Connection getOracleDBConnection(){ //get Oracle DB connection using connection parameters return null; } public void generateOraclePDFReport(String tableName, Connection con){ //get data from table and generate pdf report } public void generateOracleHTMLReport(String tableName, Connection con){ //get data from table and generate pdf report } }
Facade Design Pattern Interface
We can create a Facade pattern interface like below. Notice the use of Java Enum for type safety.
import java.sql.Connection; public class HelperFacade { public static void generateReport(DBTypes dbType, ReportTypes reportType, String tableName){ Connection con = null; switch (dbType){ case MYSQL: con = MySqlHelper.getMySqlDBConnection(); MySqlHelper mySqlHelper = new MySqlHelper(); switch(reportType){ case HTML: mySqlHelper.generateMySqlHTMLReport(tableName, con); break; case PDF: mySqlHelper.generateMySqlPDFReport(tableName, con); break; } break; case ORACLE: con = OracleHelper.getOracleDBConnection(); OracleHelper oracleHelper = new OracleHelper(); switch(reportType){ case HTML: oracleHelper.generateOracleHTMLReport(tableName, con); break; case PDF: oracleHelper.generateOraclePDFReport(tableName, con); break; } break; } } public static enum DBTypes{ MYSQL,ORACLE; } public static enum ReportTypes{ HTML,PDF; } }
Facade Design Pattern Client Program
Now lets see client code without using Facade pattern and using Facade pattern interface.
import java.sql.Connection; public class FacadePatternTest { public static void main(String[] args) { String tableName="Employee"; //generating MySql HTML report and Oracle PDF report without using Facade Connection con = MySqlHelper.getMySqlDBConnection(); MySqlHelper mySqlHelper = new MySqlHelper(); mySqlHelper.generateMySqlHTMLReport(tableName, con); Connection con1 = OracleHelper.getOracleDBConnection(); OracleHelper oracleHelper = new OracleHelper(); oracleHelper.generateOraclePDFReport(tableName, con1); //generating MySql HTML report and Oracle PDF report using Facade HelperFacade.generateReport(HelperFacade.DBTypes.MYSQL, HelperFacade.ReportTypes.HTML, tableName); HelperFacade.generateReport(HelperFacade.DBTypes.ORACLE, HelperFacade.ReportTypes.PDF, tableName); } }