Javaにおけるファサードデザインパターン
ファサードデザインパターンは、アダプターパターンやデコレーターパターンなどの構造デザインパターンの一つです。クライアントアプリケーションがシステムと簡単にやり取りできるようにするために、ファサードデザインパターンが使用されます。
ファサードデザインパターン
GoFのFacadeデザインパターンによると、とは言います。
サブシステムの一連のインターフェースに統一されたインターフェースを提供します。ファサードパターンは、より高レベルのインターフェースを定義することで、サブシステムの使用を容易にします。
以下のように述べられています:
「例えば、私達はMySQL/Oracleのデータベースを使用し、HTMLレポート、PDFレポートなどの異なる種類のレポートを生成するための一連のインタフェースを備えたアプリケーションを持っているとします。さまざまな種類のデータベースで作業するために、異なるセットのインタフェースが必要となります。クライアントアプリケーションはこれらのインタフェースを使用して必要なデータベース接続を取得し、レポートを生成することができます。しかし、複雑さが増したり、インタフェースの振る舞いの名前が混乱していたりすると、クライアントアプリケーションは管理するのが難しくなります。そのため、ここでファサードデザインパターンを適用し、既存のインタフェースの上にラッパーインタフェースを提供し、クライアントアプリケーションをサポートすることができます。」
ファサードデザインパターン – インタフェースのセット
日本語では次のように言い換えることができます。「私たちはMySqlHelperとOracleHelperという2つのヘルパーインターフェースを持つことができます。」
package com.scdev.design.facade;
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
}
}
package com.scdev.design.facade;
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パターンのインターフェースを作成することができます。型の安全性のためにJavaのEnumを使用することに注意してください。
package com.scdev.design.facade;
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パターンを使用せずにクライアントコードを見てみましょう。また、Facadeパターンインターフェースを使用したクライアントコードも見てみましょう。
package com.scdev.design.test;
import java.sql.Connection;
import com.scdev.design.facade.HelperFacade;
import com.scdev.design.facade.MySqlHelper;
import com.scdev.design.facade.OracleHelper;
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パターンインターフェースを使用することで、クライアント側で多くのロジックを回避する方法が非常に簡単で整理されたものになることが分かるでしょう。データベース接続を取得するためのJDBC Driver Managerクラスは、Facadeデザインパターンの素晴らしい例です。
ファサードデザインパターンの重要なポイント
- Facade design pattern is more like a helper for client applications, it doesn’t hide subsystem interfaces from the client. Whether to use Facade or not is completely dependent on client code.
- Facade design pattern can be applied at any point of development, usually when the number of interfaces grow and system gets complex.
- Subsystem interfaces are not aware of Facade and they shouldn’t have any reference of the Facade interface.
- Facade design pattern should be applied for similar kind of interfaces, its purpose is to provide a single interface rather than multiple interfaces that does the similar kind of jobs.
- We can use Factory pattern with Facade to provide better interface to client systems.
ファサードデザインパターンについては以上です。他のデザインパターンの記事もお楽しみに!:)