1. 程式人生 > >設計模式(Java)—Facade模式

設計模式(Java)—Facade模式

使用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");

	}

}