mohuneko’s blog

かんばる駆け出しエンジニアのブログです

【Java】Facade パターン【デザインパターン】

駆け出しエンジニアがデザインパターンをもくもく勉強します

 こんな本で勉強しています🌟

目次

Facadeパターンについて

Facade パターンとは

  • Facadeパターンは、複雑なシステムに対してシンプルな窓口(インターフェース)を用意するパターンです
  • 大きなプログラムを使って処理を行うためには、関係しあっているたくさんのクラスを適切に制御しなければなりません
  • Facadeパターンで、複雑な詳細をまとめ、高レベルでシンプルなインターフェースを提供することで、その処理を行うための"窓口"を用意します
  • こうすることで、たくさんのクラスを個別に制御しなくてよくなります

サンプルプログラム

  • Facade パターンを使って、ユーザのWebページを作成する例を取り上げます
  • 各クラスの役割は以下のようになっています
名前 役割
Database メールアドレスからユーザ名を得る
HtmlWriter HTMLファイルを作成する
PageMaker (Facade役) メールアドレスからユーザのwebサイトを作成する

f:id:mohuNeko:20201231120500p:plain

Databaseクラス

  • データベース名を指定して、それに対応したPropertiesを作成するクラスです
  • このクラスではインスタンスを作らず、getPropertiesというstaticメソッドを介してPropertiesのインスタンスを得ています
package pagemaker;

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

public class Database {
    private Database() {    // newでインスタンス生成させないためにprivate宣言
    }

    public static Properties getProperties(String dbname) { // データベース名からPropertiesを得る
        String filename = dbname + ".txt";
        Properties prop = new Properties();
        try {
            prop.load(new FileInputStream(filename));
        } catch (IOException e) {
            System.out.println("Warning: " + filename + " is not found.");
        }
        return prop;
    }
}
neko@cat.com = Neko
kiki@deliveryService.com = Kiki
nausicaa@theValleyOfTheWind.com= Nausicaa
chihiro@spiritedAway.com= Ogino Chihiro

HtmlWriterクラス

  • インスタンス作成時にWriterを与え、そのWriterに対してHTMLを出力します
  • このクラスでは、titleメソッドを最初に呼ばないといけないという制約が隠れていて、窓口であるPageMakerクラスはその制約を守るように書かれています
package pagemaker;

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

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();
    }
}

PageMakerクラス

  • publicなメソッドはmakeWelcomePageのみです
    • このメソッドにメールアドレスと出力ファイル名を指定したら、Webページが作成されます
  • HtmlWriterクラスのメソッドを呼ぶところは、このPageMakerクラスが引き受けて、外部に対しては一個のmakeWelcomePageメソッドのみを見せます
  • こうすることで、"シンプルな窓口"を実現できます
package pagemaker;

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

public class PageMaker {
    private PageMaker() {   // インスタンスは作らないのでprivate宣言する
    }

    public static void makeWelcomePage(String mailaddr, String filename) {  //シンプルな窓口
        try {
            Properties mailprop = Database.getProperties("maildata");  //maildata.txtを指定
            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();
        }
    }
}

Mainクラスで動作確認

  • pagemakerパッケージのPageMakerクラスを利用します
  • 引数で指定したメールアドレスから名前を調べ、ファイルを作成します
import pagemaker.PageMaker;

public class Main {
    public static void main(String[] args) {
        PageMaker.makeWelcomePage("kiki@deliveryService.com", "welcome.html");
    }
}
  • 実行結果

f:id:mohuNeko:20201231122134p:plain

Facadeパターンのメリット

  • Facadeパターンを使うことで、インターフェースを少なくし、複雑なものを単純に見せることができます
  • インターフェースの数を少なくすることで、外部と 疎結合 な関係にすることができます
  • つまり、パッケージを部品として再利用しやすくしてくれます。

今日のポイント

  • Facadeパターンは、複雑なシステムに対してシンプルな窓口(インターフェース)を用意するパターンです
  • 大きなプログラムの複雑な詳細をまとめ、"高レベルでシンプルなインターフェース" を提供することで、たくさんのクラスを個別に制御しなくてよくなります
  • インターフェースの数を少なくすることで、外部と 疎結合 な関係にすることができます
  • つまり、パッケージを部品として再利用しやすくしてくれます

 本日もお疲れ様です😊