外觀模式或者門(mén)面模式(又是一個(gè)奇怪的名字)犯戏,外觀模式用于幫助客戶端程序更容易的與系統(tǒng)代碼交互。
外觀模式隱藏了系統(tǒng)的復(fù)雜性,并向客戶端提供了一個(gè)可以訪問(wèn)的系統(tǒng)的接口饲漾。為子系統(tǒng)的一組接口提供了一個(gè)統(tǒng)一的訪問(wèn)接口,使子系統(tǒng)更容易被訪問(wèn)或使用缕溉。
簡(jiǎn)單的說(shuō)考传,該模式就是把一些復(fù)雜的流程封裝成一個(gè)接口供給外部用戶更簡(jiǎn)單的使用。
假設(shè)我們有一個(gè)具有很多接口的應(yīng)用程序证鸥,用吧MySql/Oracle等數(shù)據(jù)庫(kù)并生成不同類(lèi)型的報(bào)告僚楞,例如HTML報(bào)告勤晚,PDF報(bào)告等。
所以我們將有不同的接口來(lái)處理不同類(lèi)型的數(shù)據(jù)庫(kù)∪郑現(xiàn)在赐写,客戶端應(yīng)用程序可以使用這些接口來(lái)獲取所需的數(shù)據(jù)庫(kù)連接并生成報(bào)告。
但當(dāng)業(yè)務(wù)復(fù)雜性不斷增加或接口的行為命名令人困惑膜赃,客戶端程序會(huì)發(fā)現(xiàn)很難管理它挺邀。
所以這里我們可以使用外觀模式,提供一個(gè)頂層接口包裝來(lái)幫助客戶端程序跳座。
Facade Design Pattern – Set of Interfaces
我們可能有兩個(gè)幫助類(lèi)MySqlHelper和OracleHelper
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
}
}
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.
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
測(cè)試程序
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);
}
}
正如你所看到的端铛,使用Facade模式避免在客戶端擁有大量邏輯,使程序更簡(jiǎn)單更清晰疲眷。 JDBC Driver Manager類(lèi)獲取數(shù)據(jù)庫(kù)連接是外觀模式的一個(gè)很好的例子禾蚕。
Facade Design Pattern Important Points
- 對(duì)客戶端程序來(lái)說(shuō),外觀模式更像是一個(gè)helper類(lèi)咪橙, 它不會(huì)隱藏系統(tǒng)的接口夕膀。是否使用外觀模式完全取決于客戶端代碼。
- 外觀模式可以應(yīng)用到開(kāi)發(fā)過(guò)程中的任意地方美侦,通常的當(dāng)接口的數(shù)量越來(lái)越多系統(tǒng)越來(lái)越復(fù)雜時(shí)考慮使用它产舞。
- 子系統(tǒng)的接口不會(huì)意識(shí)到Facade的存在,他們也不應(yīng)該引用Facade類(lèi)的任何方法菠剩。
- 門(mén)面設(shè)計(jì)模式應(yīng)當(dāng)盡可能少的提供接口方法易猫,它的目的是提供一個(gè)單一的接口而不是多個(gè)接口來(lái)解決一類(lèi)問(wèn)題。
- 通過(guò)外觀模式可以為客戶端提供更友好的接口具壮。