設計模式(Java)—Facade模式
阿新 • • 發佈:2018-12-11
使用Facade模式可以為互相關聯在一起的錯綜複雜的類整理出高層介面,其中的Facade角色可以讓系統對外只有一個簡單的介面。
示例程式 該程式只有三個簡單類,一個是用於從郵件地址中獲取使用者名稱字的資料庫類,一個用於編寫HTML檔案的類,以及一個扮演Facade角色並提供高層介面的類。
Database類 Database類可獲取指定資料庫名所對應的Properties的例項,我們無法生成該類的任何例項,只能通過它的getProperties靜態方法獲取Properties的例項。
package Facade; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; public class Database { private Database(){ }//防止外部new出Database的例項,所以宣告為private public static Properties getProperties(String dbname){ String filename = dbname+".txt"; Properties properties = new Properties(); try { properties.load(new FileInputStream(filename)); } catch (IOException e) { // TODO: handle exception e.printStackTrace(); } return properties; } }
資料檔案(maildata.txt)
[email protected]=Hirohi yuki
[email protected]=Hanako stao
[email protected]=Tomura hioq
[email protected]=Mamoru shio
資料檔案路徑
HtmlWriter類 該類用於編寫簡單的Web頁面,我們在生成HtmlWriter類的時候賦予其Writer,然後使用該Writer輸出HTML。
package Facade; import java.io.IOException; import java.io.Writer; public class HtmlWriter { private Writer writer; public HtmlWriter(Writer writer) { // TODO Auto-generated constructor stub 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>"); writer.close(); } }
PageMaker類 該類使用Database類和HtmlWrite類來生成指定使用者的Web頁面。
package Facade; import java.io.FileWriter; import java.io.IOException; import java.util.Enumeration; import java.util.Properties; public class PageMaker { private PageMaker(){ } public static void makeWelcomePage(String mailaddr,String filename){ try { Properties mailpop = Database.getProperties("maildata"); String username = mailpop.getProperty(mailaddr); HtmlWriter writer = new HtmlWriter(new FileWriter(filename)); writer.title("Welcome to"+username+"'s page!"); writer.paragraph(username+"歡迎來到"+username+"的主頁"); writer.paragraph("等著你的郵件!"); writer.mailto(mailaddr, username); writer.close(); System.out.println(filename+" is created by "+mailaddr+" ("+username+" )"); } catch (IOException e) { // TODO: handle exception e.printStackTrace(); } } }
對外只提供makeWelcomePage介面。
Main類
package Facade;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
PageMaker.makeWelcomePage("[email protected]", "welcome.html");
}
}
程式中如果有很多類和方法,我們決定到底應該使用哪個類或是方法時就很迷茫。有時,類和方法的呼叫順序也很容易弄錯,必須格外注意。因此,如果有一個能使介面變少的Facade角色是一件多麼美好的事情。 介面變少意味著程式與外部的關係弱化了,這樣更容易使我們的包作為元件被複用。
練習: 在PageMaker類中增加一個makeLinkPage方法,使其可以依據檔案中的使用者郵件地址製作出郵件地址超連結集合。 PageMaker類
package Facade;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;
public class PageMaker {
private PageMaker(){
}
public static void makeWelcomePage(String mailaddr,String filename){
try {
Properties mailpop = Database.getProperties("maildata");
String username = mailpop.getProperty(mailaddr);
HtmlWriter writer = new HtmlWriter(new FileWriter(filename));
writer.title("Welcome to"+username+"'s page!");
writer.paragraph(username+"歡迎來到"+username+"的主頁");
writer.paragraph("等著你的郵件!");
writer.mailto(mailaddr, username);
writer.close();
System.out.println(filename+" is created by "+mailaddr+" ("+username+" )");
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
public static void makeLinkPage(String filename){
try {
Properties mailpop = Database.getProperties("maildata");
HtmlWriter writer = new HtmlWriter(new FileWriter(filename));
writer.title("Linkpage");
Enumeration enumeration = mailpop.propertyNames();
while(enumeration.hasMoreElements()){
String mailaddr = (String)enumeration.nextElement();
String username = mailpop.getProperty(mailaddr,"(unknown)");
writer.mailto(mailaddr, username);
}
writer.close();
System.out.println(filename + " is created.");
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
Main類
package Facade;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
PageMaker.makeWelcomePage("[email protected]", "welcome.html");
PageMaker.makeLinkPage("linkpage.html");
}
}