提供对外简单窗口-Facade模式

118 阅读2分钟

1、引入

facade,译为 外观; (建筑物的)正面,立面; (虚假的)表面,外表

对于一个复杂的系统,往往有多种构件,而对于使用者来说,完全使用基本的构建搭建是困难的,通常我们需要提供更为容易使用的上层API,封装底层的API。

而这种“封装”在软件开发中是经常用到的:

  • 从机器语言到低级、中级、高级语言,可以视为一种封装。
  • 从语言的基础语法到常用类库,可以视为一种封装
  • 从基础语法和常用库到框架,可以视为一种封装

2、示例

在此,给出一个构建欢迎网页的例子。在本例中,网页构建需要数据库与网页搭建API协同,而引入了Facade模式后,只需要传入用户邮箱地址和网页存放位置,即可构建出一个简单的网页。

2.1、数据库

使用txt文本作为数据库,用K-V方式存储

image.png 操作数据库的类:

public class Database {
    public Database() {
    }

    public static Properties getProperties(String dbname) {
        String filename=dbname+".txt";
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream(filename));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return properties;
    }
}

2.2、网页搭建API

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

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

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

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

2.3、上层Facade

public class PageMaker {
    private PageMaker() {
    }

    public static void makeWelcomePage(String mailAddress, String filename) {
        try {
            Properties properties = Database.getProperties("./src/facade/example/data");
            String username = properties.getProperty(mailAddress);
            HtmlWriter htmlWriter = new HtmlWriter(new FileWriter(filename));
            htmlWriter.title("Welcome to "+username+"'s page");
            htmlWriter.paragraph(username+"欢迎来到"+username+"的主页");
            htmlWriter.paragraph("等待你的邮件");
            htmlWriter.mailto(mailAddress, username);
            htmlWriter.close();
            System.out.println(filename+"is created for "+mailAddress+"("+username+")");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.4、测试

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

运行结果:

image.png

3、tips

  • 虽然封装方便了我们使用,但是一定程度上牺牲了灵活性,因此完成部分工作时仍然需要使用基础的库。
  • 在大型系统中,往往可以使用多级facade,通过层层封装方便系统的使用和维护