Design Pattern | Facade Pattern(ファサードパターン)

Facadeパターンとは?

  • Facadeという英単語は正面という意味である。
  • 「建物の正面」を意味する単語であり、あるソフトウェアの別の大きなコード部分に対して、簡略化されたインターフェースを提供するデザインパターンを意味する。
  • 大きなプログラムを使って処理を行うには、関連している多くのクラスを適切に制御しなければならない。その処理を行うための窓口を作っておけば、多くのクラスを個別に制御しなくてもよい。
  • Facadeパターンは、複雑なシステムに対する簡単な窓口を用意する方式である。
  • Facadeオブジェクトは、複雑なソフトウェアの外側のコードがライブラリ内部のコードに依存することを減らし、複雑なソフトウェアを使えるように簡単なインターフェースを提供する。
  • GoFのデザインパターンでは、構造に関するデザインパターンに分類される。

Facadeパターンのサンプルプログラム

ユーザーのWebページを作るサンプルプログラムである。

Class Diagram
Facade Pattern Class Diagram

1. PageMakerクラス

メールアドレスからユーザーのWebページを作るクラスである。このクラスがFacadeになる。

PageMaker.java

package com.devkuma.designpattern.structural.facade.pagemaker;

import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

public class PageMaker {

    private PageMaker() {}

    public static void makeWelcomePage(String mailaddr, String filename) {
        try {
            Properties mailProp = Database.getProperties("maildata");
            String username = mailProp.getProperty(mailaddr);
            HtmlWriter writer = new HtmlWriter(new FileWriter(filename));
            writer.title("Welcome to " + username + "'s page!");
            writer.paragraph(username + "의 페이지에 어서오세요.");
            writer.paragraph("문의 사항을 메일을 보내주세요.");
            writer.mailto(mailaddr, username);
            writer.close();
            System.out.println(filename + " is created for " + mailaddr + " (" + username + ")");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2. HtmlWriterクラス

HTMLファイルを作成するクラスである。

HtmlWriter.java

package com.devkuma.designpattern.structural.facade.pagemaker;

import java.io.IOException;
import java.io.Writer;

public class HtmlWriter {

    private Writer writer;

    public HtmlWriter(Writer writer) {
        this.writer = writer;
    }

    public void title(String title) throws IOException {
        writer.write("<html>");
        writer.write("<head>");
        writer.write("<title>" + title + "</title>");
        writer.write("</head>");
        writer.write("<body>\n");
        writer.write("<h1>" + title + "</h1>\n");
    }

    public void paragraph(String msg) throws IOException {
        writer.write("<p>" + msg + "</p>\n");
    }

    public void link(String href, String caption) throws IOException {
        paragraph("<a href=\"" + href + "\">" + caption + "</a>");
    }

    public void mailto(String mailaddr, String username) throws IOException {
        link("mailto:" + mailaddr, username);
    }

    public void close() throws IOException {
        writer.write("</body>");
        writer.write("</html>\n");
        writer.close();
    }
}

3. Databaseクラス

メールアドレスからユーザー名を取得するクラスである。

Database.java

package com.devkuma.designpattern.structural.facade.pagemaker;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class Database {

    private Database() {
    }

    public static Properties getProperties(String dbname) {
        ClassLoader loader = Database.class.getClassLoader();
        String file = loader.getResource("facade/pagemaker/" + dbname + ".txt").getFile();
        Properties prop = new Properties();
        try {
            prop.load(new FileInputStream(file));
        } catch (IOException e) {
            System.out.println("Warning: " + file + " is not found.");
        }
        return prop;
    }
}

4. maildataデータベース

データベースファイルである。

maildata.txt

devkuma@devkuma.com=dekuma
ariakuma@devkuma.com=ariakuma
kimkc@devkuma.com=kim

5. Mainクラス

メイン処理を実行するクラスである。

Main.java

package com.devkuma.designpattern.structural.facade;

import com.devkuma.designpattern.structural.facade.pagemaker.PageMaker;

public class Main {
    public static void main(String[] args) {
        PageMaker.makeWelcomePage("devkuma@devkuma.com", "welcome.html");
    }
}

6. 実行結果

<html><head><title>Welcome to devkuma's page!</title></head><body>
<h1>Welcome to devkuma's page!</h1>
<p>devkuma의 페이지에 어서오세요.</p>
<p>문의 사항을 메일을 보내주세요.</p>
<p><a href="mailto:devkuma@devkuma.com">devkuma</a></p>
</body></html>

Facadeパターンのメリット

クラスやメソッドが多いと、プログラマーはどれを使えばよいか迷ったり、呼び出し順序に注意しなければならない。注意が必要ということは、それだけミスしやすいということである。
Facadeパターンを使うと、インターフェースを減らし、複雑なものを単純に見せることができる。
インターフェースの数が少ないということは、外部との結合が疎であるとも表現できる。つまり、疎結合になり、パッケージを部品として再利用しやすくする。