設計模式(九):外觀模式

来源:http://www.cnblogs.com/jenkinschan/archive/2016/08/07/5746511.html
-Advertisement-
Play Games

一、概述 外觀模式提供了一個統一的介面,用來訪問子系統中的一群介面。外觀定義了一個高層介面,讓子系統更容易使用。 二、解決問題 在上一講中,我們學習了適配器模式,它是用來轉換一個介面的,而外觀模式可以理解為轉換一群介面,客戶只要調用一個介面,而不用調用多個介面就可以達到目的。想想現實生活中例子,我們 ...


一、概述

  外觀模式提供了一個統一的介面,用來訪問子系統中的一群介面。外觀定義了一個高層介面,讓子系統更容易使用。

二、解決問題

  在上一講中,我們學習了適配器模式,它是用來轉換一個介面的,而外觀模式可以理解為轉換一群介面,客戶只要調用一個介面,而不用調用多個介面就可以達到目的。想想現實生活中例子,我們在pc上安裝軟體的時候經常有預設安裝或者是一鍵安裝選項(省去選擇安裝目錄、安裝的組件等等),還有就是手機的重啟功能(把關機和啟動合為一個操作)。總之,外觀模式就是解決多個複雜介面帶來的使用困難,起到簡化用戶操作的作用。

三、結構類圖

四、成員角色

  客戶(Client):直接調用外觀介面就可以使用子系統了。

  外觀(Facade):封裝子系統的一個或者多個介面,並提供一個統一的介面給客戶端調用。

五、應用實例

  最近幾年一直比較流行智能家居,在我看來就是很多家電連了網,我們可以在手機上操作這些家電,給我們帶來了很大的便利。下麵我們假設這樣一種場景,我們晚上回到家需要開燈、開空調、關窗、拉窗帘、放音樂,完成這五個動作我們才可以舒舒服服地躺在沙發上,緩解一天工作的辛勞。如果每天要進行這樣的操作就太麻煩了,現在我們的智能家居來了,他給我們提供了一個手機app,只要將近到家的時候按下一個按鈕,各種家電就會自動工作,營造一個舒適的家庭環境等著我們回來。來看看我們是怎麼做到的。

  第一步、創建各種電器

package facade.pattern;
//電燈
public class Light {
	public void on(){
		System.out.println("電燈打開了");
	}
	
	public void off(){
		System.out.println("電燈關了");
	}
}

  

package facade.pattern;

//空調
public class Aircondition {
	public void on(){
		System.out.println("空調打開了");
	}
	
	public void off(){
		System.out.println("空調關了");
	}
}

  

package facade.pattern;

//窗
public class Window {
	public void on(){
		System.out.println("窗打開了");
	}
	
	public void off(){
		System.out.println("窗關了");
	}
}

  

package facade.pattern;

//窗帘
public class Curtain {
	public void on(){
		System.out.println("窗帘打開了");
	}
	
	public void off(){
		System.out.println("窗帘關了");
	}
}

  

package facade.pattern;

//mp3播放器
public class Mp3player {
	public void on(){
		System.out.println("mp3播放器打開了");
	}
	
	public void off(){
		System.out.println("mp3播放器關了");
	}
}

  第二步、創建手機app

package facade.pattern;

//手機app
public class App {
	private Light light;
	private Aircondition aircondition;
	private Window window;
	private Curtain curtain;
	private Mp3player mp3;
	
	//實例化時初始化電器
	public App(Light light, Aircondition aircondition, Window window,
			Curtain curtain, Mp3player mp3) {
		super();
		this.light = light;
		this.aircondition = aircondition;
		this.window = window;
		this.curtain = curtain;
		this.mp3 = mp3;
	}

	//設置在家模式,開啟需要的家電
	public void atHome(){
		light.on();
		aircondition.on();
		window.off();
		curtain.off();
		mp3.on();
	}
}

  第三步、測試手機app

package facade.pattern;

public class AppTest {
	public static void main(String[] args){
		Light light = new Light();
		Aircondition aircondition = new Aircondition();
		Window window = new Window();
		Curtain curtain = new Curtain();
		Mp3player mp3 = new Mp3player();		
		App app = new App(light,aircondition,window,curtain,mp3);
		//以上代碼客戶可以不用知道
		
		System.out.println("---用手機設置智能家居,設置為在家模式---");
		
		//客戶一鍵操作設置在家模式
		app.atHome();
	}
}

運行結果:

    

六、優點和缺點

  1、優點

  (1)、外觀不只是簡化了介面,也將客戶從組建的子系統中解耦。客戶只需關註外觀提供的介面,而不需要關心外觀所封裝的子系統的類。

  (2)、提供簡化的介面的同時,依然將系統完整的功能暴露出來,以供需要的人使用。

七、使用場景

  1、當需要簡化並統一一個很大的介面或者簡化一群複雜的介面時使用外觀。

  2、希望客戶從一個複雜的子系統中解耦。

八、在外觀模式中可以使用的設計原則--最少知識原則

  最少知識原則定義:只和你的密友交談。

  最少知識原則設計方針是在就任何對象而言,在該對象的方法內,我們只應該調用屬於以下範圍的方法:

  1、該對象本身 

package facade.pattern;

public class LightTest {
	public void on(){
		System.out.println("電燈打開了");
	}
	
	public void off(){
		System.out.println("電燈關了");
	}
	
	public void test(){
		//在方法中調用本類中的其他方法
		on();
	}
}

  2、被當做方法的參數而傳遞進來的對象(外觀模式手機app的例子)

//手機app
public class App {
        //外出模式
	public void goOut(Light light, Aircondition aircondition, Window window,
			Curtain curtain, Mp3player mp3){
		light.off();
		aircondition.off();
		window.on();
		curtain.on();
		mp3.off();
	}
}

  3、此方法所創建或實例化的任何對象

//手機app
public class App {
	private Light light;
	private Aircondition aircondition;
	private Window window;
	private Curtain curtain;
	private Mp3player mp3;
    
        public App(){

        }

	public Mp3player getMp3() {
		return mp3;
	}

	public void setMp3(Mp3player mp3) {
		this.mp3 = mp3;
	}

	public void startMp3(){
		mp3.on();
	}
} 

  //不建議如下使用

public void startMp3player(){
	Mp3player mp3 = new App().getMp3();
	mp3.on();
}

  應該改為

public void startMp3player(){
	new App().startMp3();	
}

  4、對象的任何組件

//手機app
public class App {
	private Light light;
	private Aircondition aircondition;
	private Window window;
	private Curtain curtain;
	private Mp3player mp3;
    
        public App(){

        }

        //在該方法中,可以使用組件mp3的任何方法
	public void startMp3(){
		mp3.on();
	}
} 

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.開通語音識別(預設關閉) 2.語音識別 請註意,開通語音識別後,用戶每次發送語音給公眾號時,微信會在推送的語音消息XML數據包中,增加一個Recognition欄位(註:由於客戶端緩存,開發者開啟或者關閉語音識別功能,對新關註者立刻生效,對已關註用戶需要24小時生效。開發者可以重新關註此帳號進行 ...
  • 學習Hibernate ,我們首先要知道為什麼要學習它?它有什麼好處?也就是我們為什麼要學習框架技術? 還要知道 什麼是Hibernate? 為什麼要使用Hibernate? Hibernate的配置文件的作用是什麼? Hibernate映射文件的作用是什麼? Hibernate持久化對象的狀態有哪 ...
  • nodejs windows下的調用方法: C:\Users\owen>node helloworld.jsHello WorldHello: 25 C:\Users\owen>node getmodule.jsHello BYVoid C:\Users\owen>node app.jsHTTP S ...
  • 在Eclipse 創建動態WEB 工程,在src 下 創建 config.xml: 提示Error: Content is not allowed in prolog 查看為DOM 解析xml error, 查看網上加入 dom4j.jar,refrensh並無效果; // 解決辦法: 用記事本創建 ...
  • 實例運行結果如下 實例運行結果如下 ...
  • 今天寫了個java類連接oracle,拋出了這個問題 java.sql.SQLException: No suitable driver found for jdbc:oracle:thin:@127.0.0.1:1521:orcl; 很顯然是URL錯誤,以前碰到過類似的問題,故一起總結一下。 以前 ...
  • 前言:關於EL表示式開發用的非常多,現在我們回顧一下關於如果去操作EL表達式 1:EL表達式語法 所有EL表達式都是由{開始}結束,表達式中用.和[]操作符來訪問數據比喻${user.userName}、${user["userName"]}是等效的。 2:幾個重要的操作符 算術,邏輯,關係操作符和 ...
  • 學習設計模式的過程中,發現相關的作者們都會用UML類圖來表示一個模式的整體脈絡,這種方式確實直觀明瞭,既能體現巨集觀思路、又能兼顧實現細節。真的是很妙的工具。在開始正式學習設計模式之前,有必要對UML有個大概的掌握。然後,日後有望解鎖更多關於UML方面的技能,比如說:建模。哈哈,有點小興奮呢。 UML ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...