【デザインパターン】JavaのFacadeパターンについて
今回はfacadeパターンについて解説します。
Facade
今まで作ってきた一つの概念としての処理(ポケモンバトル、コメント機能、HTML文書作成など)をインターフェース化するイメージです。 そこまで難しくないです。 今までは上記のパターンを作ったらMainクラスで実装していました。 しかし実際のプログラムではこれらのMainクラスも一つの処理として組み合わせて、一つのプログラムを作り上げていきます。
その際にいちいち各クラスの中身まで見ていたら大変膨大な量になってしまいます。 そのため、今までMainクラスとして扱っていた部分を窓口として外から使いやすくしたものがFacadeパターンです。
実装
今回はユーザのWebページを作ります。 データベースに見立てたテキストファイルからユーザの情報を取得し、テンプレートを用いてHTMLファイルを作成していきます。
Database
簡易的にテキストファイルに(email, username)のデータストアを作成します。 getResourceAsStreamで現在のクラスと同じ階層のfilenameのファイルを探しInputStreamとしてPropertiesクラスに流し込み、テキストファイルから読み込んだ文字列をキーバリューのデータとして保存します。
import java.util.Properties;
public class Database {
public Database() {
}
public Properties getProperties(String dbname) {
String filename = dbname + ".txt";
Properties prop = new Properties();
try {
prop.load(getClass().getResourceAsStream(filename));
} catch (Exception e) {
System.out.println("Warning: " + filename + " is not found.");
}
return prop;
}
}
下記のmaildata.txtはあらかじめ作っておきます。
bob@example.com=bob jones
alice@example.com=alice smith
kurimatsu@example.com=teppei kurimatsu
HtmlWriter
ここでは簡単なWebページをもらった変数を用いて作ります。
import java.io.Writer;
public class HtmlWriter {
private Writer writer;
public HtmlWriter(Writer writer) {
this.writer = writer;
}
public void title(String title) {
String html = """
<html>
<head>
<title>%s</title>
</head>
<body>
<h1>%s</h1>
""";
try {
writer.write(String.format(html, title, title));
} catch (Exception e) {
e.printStackTrace();
}
}
public void paragraph(String msg) {
String html = """
<p>%s</p>
""";
try {
writer.write(String.format(html, msg));
} catch (Exception e) {
e.printStackTrace();
}
}
public void mailto(String mailaddr, String username) {
String html = """
<a href="mailto:%s">%s</a>
""";
try {
writer.write(String.format(html, mailaddr, username));
} catch (Exception e) {
e.printStackTrace();
}
}
public void close() {
String html = """
</body>
</html>
""";
try {
writer.write(html);
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
PageMaker
ここが先ほどの窓口
にあたります。
今までのMainクラスに近いイメージです。
Database、HtmlWriterを用いてページを作ります。
ユーザからはこれらのクラスのメソッドが何をしているのかを隠しなるべくシンプルにしたいため、作成するユーザのメールとファイル名をもらい後の処理はここのPageMakerに任せてしまいましょう。
import java.io.FileWriter;
import java.util.Properties;
public class PageMaker {
private PageMaker() {
}
public static void makeWelcomePage(String mailaddr, String filename) {
try {
Database db = new Database();
Properties mailprop = db.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 (Exception e) {
e.printStackTrace();
}
}
}
実行
Main
メインクラスが驚くほどシンプルになりました。 これから別の機能を作ることになっても、エンジニアはこのPageMakerの先で何が行われているかは意識しなくてすみました。
public class Main {
public static void main(String[] args) {
PageMaker.makeWelcomePage("kurimatsu@example.com", "welcome.html");
}
}
実行結果
下記のHTMLが作成されていれば成功です。
<html>
<head>
<title>Welcome to teppei kurimatsu's page!</title>
</head>
<body>
<h1>Welcome to teppei kurimatsu's page!</h1>
<p>teppei kurimatsuのページへようこそ。</p>
<p>メール待っていますね。</p>
<a href="mailto:kurimatsu@example.com">teppei kurimatsu</a>
</body>
</html>
今回作成したこのFacadeパターンを集めて新しい機能を作ったとしましょう。 例えばCSSを作る機能をFacadeパターンで作成します。 すると、HTMLにCSSを付与したファイルを作成することができます。
これも一つの機能として考えれば、またFacadeパターンを使用してユーザからは実装を隠してデザインが適用されたファイルを作成する「DesignedPageMaker」も作れます。
See you later 👋
0