JavaでのFacadeデザインパターン

Facadeデザインパターンは、構造型デザインパターンアダプターパターンデコレーターパターンなど)の一つです。Facadeデザインパターンは、クライアントアプリケーションがシステムと簡単にやり取りするのを支援するために使用されます。

Facadeデザインパターン

GoFによれば、Facadeデザインパターンは次のように定義されます:

サブシステムの一連のインターフェースに統一されたインターフェースを提供します。Facadeパターンは、サブシステムをより使いやすくするために、より高いレベルのインターフェースを定義します。

もしも、私たちがMySql/Oracleデータベースを使用し、HTMLレポートやPDFレポートなどの異なるタイプのレポートを生成するためのインターフェースのセットを持つアプリケーションがあるとします。したがって、異なる種類のデータベースと連携するために異なるセットのインターフェースが必要になります。クライアントアプリケーションはこれらのインターフェースを使用して必要なデータベース接続を取得し、レポートを生成することができます。しかし、複雑さが増すか、インターフェースの動作名が混乱する場合、クライアントアプリケーションはそれを管理するのが難しくなるでしょう。そのため、Facadeデザインパターンを適用し、既存のインターフェースの上にラッパーインターフェースを提供することができます。

Facadeデザインパターン – インターフェースのセット

私たちはMySqlHelperOracleHelperという2つのヘルパーインターフェースを持つことができます。

package com.journaldev.design.facade;

import java.sql.Connection;

public class MySqlHelper {
	
	public static Connection getMySqlDBConnection(){
		//接続パラメータを使用してMySql DB接続を取得
		return null;
	}
	
	public void generateMySqlPDFReport(String tableName, Connection con){
		//テーブルからデータを取得し、PDFレポートを生成
	}
	
	public void generateMySqlHTMLReport(String tableName, Connection con){
		//テーブルからデータを取得し、PDFレポートを生成
	}
}
package com.journaldev.design.facade;

import java.sql.Connection;

public class OracleHelper {

	public static Connection getOracleDBConnection(){
		//接続パラメータを使用してOracle DB接続を取得
		return null;
	}
	
	public void generateOraclePDFReport(String tableName, Connection con){
		//テーブルからデータを取得し、PDFレポートを生成
	}
	
	public void generateOracleHTMLReport(String tableName, Connection con){
		//テーブルからデータを取得し、PDFレポートを生成
	}
	
}

ファサードデザインパターンのインタフェース

以下のようにファサードパターンのインタフェースを作成することができます。タイプセーフティのためにJava Enumの使用に注意してください。

package com.journaldev.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;
	}
}

ファサードデザインパターンのクライアントプログラム

では、ファサードパターンを使用しない場合とファサードパターンインタフェースを使用する場合のクライアントコードを見てみましょう。

package com.journaldev.design.test;

import java.sql.Connection;

import com.journaldev.design.facade.HelperFacade;
import com.journaldev.design.facade.MySqlHelper;
import com.journaldev.design.facade.OracleHelper;

public class FacadePatternTest {

	public static void main(String[] args) {
		String tableName="Employee";
		
		// ファサードを使用せずにMySqlのHTMLレポートとOracleのPDFレポートを生成する
		Connection con = MySqlHelper.getMySqlDBConnection();
		MySqlHelper mySqlHelper = new MySqlHelper();
		mySqlHelper.generateMySqlHTMLReport(tableName, con);
		
		Connection con1 = OracleHelper.getOracleDBConnection();
		OracleHelper oracleHelper = new OracleHelper();
		oracleHelper.generateOraclePDFReport(tableName, con1);
		
		// ファサードを使用してMySqlのHTMLレポートとOracleのPDFレポートを生成する
		HelperFacade.generateReport(HelperFacade.DBTypes.MYSQL, HelperFacade.ReportTypes.HTML, tableName);
		HelperFacade.generateReport(HelperFacade.DBTypes.ORACLE, HelperFacade.ReportTypes.PDF, tableName);
	}

}

ファサードパターンのインタフェースを使用すると、クライアント側で多くのロジックを持つことを避けるために、はるかに簡単でクリーンな方法であることがわかります。データベース接続を取得するためのJDBC Driver Managerクラスは、ファサードデザインパターンの素晴らしい例です。

ファサードデザインパターンの重要なポイント

  • ファサードデザインパターンは、クライアントアプリケーションのためのヘルパーのようなものであり、クライアントからのサブシステムのインターフェースを隠すものではありません。ファサードを使用するかどうかは、完全にクライアントコードに依存します。
  • ファサードデザインパターンは、開発のどの段階でも適用できますが、通常はインターフェースの数が増え、システムが複雑になったときに使用されます。
  • サブシステムのインターフェースはファサードを意識しておらず、ファサードのインターフェースへの参照を持つべきではありません。
  • ファサードデザインパターンは、類似した種類のインターフェースに適用されるべきであり、同様の仕事を行う複数のインターフェースではなく、単一のインターフェースを提供することを目的としています。
  • ファサードと一緒にファクトリーパターンを使用して、クライアントシステムにより良いインターフェースを提供することができます。

ファサードデザインパターンに関する情報は以上です。追加のデザインパターンの記事をお楽しみに。 🙂

Source:
https://www.digitalocean.com/community/tutorials/facade-design-pattern-in-java