【JAVA設計模式】外觀模式(Facade Pattern)

一 ?定義

為子系統中的一組接口提供一個一致的界面。Facade模式定義了一個高層的接口,這個接口使得這一子系統更加easy使用。


二 ?案例

一個子系統中擁有3個模塊。每一個模塊中都有3個方法。當中一個為client調用方法,其它兩個則為各子模塊間互相調用方法。此時有例如以下需求,client為完畢功能。須要組合3個模塊中的方法才干實現功能。

三 ?未使用模式情況

/*** @Description A模塊* @author jerry * @date 2016年4月11日下午2:16:04*/
public interface AModuleApi {public void a1();	//此方法主要用于外部調用public void a2();	//下面雙方法主要用于子系統內部間調用public void a3();
}
/*** @Description A模塊實現* @author jerry * @date 2016年4月11日下午2:17:10*/
public class AModuleImpl implements AModuleApi {@Overridepublic void a1() {System.out.println("調用了A模塊");}@Overridepublic void a2() {//TODO 主要用于子模塊間互相調用}@Overridepublic void a3() {//TODO 主要用于子模塊間互相調用}
}
/*** @Description B模塊* @author jerry * @date 2016年4月11日下午2:16:12*/
public interface BModuleApi {public void b1();	//此方法主要用于外部調用public void b2();	//下面雙方法主要用于子系統內部間調用public void b3();
}
/*** @Description B模塊實現* @author jerry * @date 2016年4月11日下午2:17:10*/
public class BModuleImpl implements BModuleApi {@Overridepublic void b1() {System.out.println("調用了B模塊");}@Overridepublic void b2() {//TODO 主要用于子模塊間互相調用}@Overridepublic void b3() {//TODO 主要用于子模塊間互相調用}
}
同理。C模塊也是如此,篇幅原因。這里不貼代碼了,須要代碼能夠從我github下clone,文末會給出地址。
client調用例如以下:
public class Client {public static void main(String[] args) {AModuleApi a = new AModuleImpl();a.a1();BModuleApi b = new BModuleImpl();b.b1();CModuleApi c = new CModuleImpl();c.c1();}
}
相信非常easy能夠寫出這種代碼。

細致想想能夠發現,假設這樣寫。會存在例如以下問題:

  1. 代碼耦合度太高,client與子系統中各模塊都有關聯。一旦子系統有什么更改,會涉及到client的改動。
  2. 對client學習成本太高。client須要學習各個模塊中每一個public方法。知道其什么含義后才干進行調用。


四 ?使用模式的情況

我們能夠在系統這端(即外觀模式屬于系統這端,若屬于客戶這端。仍然須要客戶去了解每一個模塊每一個方法意義,這樣無不論什么意義。) 加入一個外觀類,由外觀類重組須要調用的方法,例如以下所看到的:
/*** @Description 外觀類,通常設計成單例* @author jerry * @date 2016年4月11日下午2:43:26*/
public class Facade {private Facade(){}public static void test(){AModuleApi a = new AModuleImpl();a.a1();BModuleApi b = new BModuleImpl();b.b1();CModuleApi c = new CModuleImpl();c.c1();}
}
public class Client {public static void main(String[] args) {
//		AModuleApi a = new AModuleImpl();
//		a.a1();
//		BModuleApi b = new BModuleImpl();
//		b.b1();
//		CModuleApi c = new CModuleImpl();
//		c.c1();Facade.test();}
}
這樣一來。client僅僅要與外觀類打交道就可以,從而更好地實現了client和子系統各模塊的耦合性。

使用外觀的目的: 不是給子系統加入新的功能接口,而是讓外部降低對子系統內部多個模塊的直接交互。松散耦合,從而可以讓外部更簡單地使用子系統。

當然有時你會有這種需求,client可能僅僅須要調用兩個模塊就可以,那么現有的外觀模式就無法使用了,僅僅好繞開外觀類。直接找各模塊進行調用。此外,你是否發現。我的ABC模塊里面除了有供外部調用的方法外。還有各模塊間互相調用的方法,這些方法本不須要client了解。暴露了過多內部細節。會讓client產生疑惑,這就是“接口污染? 。要解決問題,我們能夠將Facade類定義為接口,并對事實上現,使用工廠模式對其創建實例,例如以下所看到的:
public interface FacadeApi {public void a1();public void b1();public void c1();/*** @Description 原有方法,將各模塊方法組合調用* @return void* @throws */public void test();
}
/*** @Description 外觀接口實現* @author jerry * @date 2016年4月11日下午3:19:25*/
public class FacadeImpl implements FacadeApi {@Overridepublic void a1() {new AModuleImpl().a1();}@Overridepublic void b1() {new BModuleImpl().b1();}@Overridepublic void c1() {new CModuleImpl().c1();}@Overridepublic void test() {a1();b1();c1();}
}
/*** @Description 外觀接口實現* @author jerry * @date 2016年4月11日下午3:19:25*/
public class FacadeImpl implements FacadeApi {@Overridepublic void a1() {new AModuleImpl().a1();}@Overridepublic void b1() {new BModuleImpl().b1();}@Overridepublic void c1() {new CModuleImpl().c1();}@Overridepublic void test() {a1();b1();c1();}
}
public class Client {public static void main(String[] args) {
//		AModuleApi a = new AModuleImpl();
//		a.a1();
//		BModuleApi b = new BModuleImpl();
//		b.b1();
//		CModuleApi c = new CModuleImpl();
//		c.c1();//		Facade.test();FacadeApi api = Factory.createFacade();api.test();}
}
這樣以后,就對client降低了模塊內部方法的暴露。

五 ?總結

外觀模式的本質:封裝交互。簡化調用
何時使用外觀模式:
  1. 假設你希望為一個復雜的子系統提供一個簡單接口
  2. 假設構建多層結構的系統。能夠考慮使用外觀模式,使用外觀對象作為每層的入口,這樣能夠簡化層間調用,能夠減少耦合度。
------------------------------------------------------------------------------------------------------------------------------------------
Github: ?https://github.com/jerry-sc/designPattern
Reference:《研磨設計模式》

轉載于:https://www.cnblogs.com/yangykaifa/p/7290448.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/253837.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/253837.shtml
英文地址,請注明出處:http://en.pswp.cn/news/253837.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

return的用處

#include "stdio.h" main() {int a,b1,c0;for(a1;a<5;a){ cca;}printf("%d",c);return ;printf("hello word"); } 輸出結果是10并沒有hello word&#xff1b;return將不會執行下面的語句。轉載于:https://www.cnblogs.com/doublekai/p/6148…

靜態時序分析——Clock Gating check

門控時鐘是RTL級進行低功耗設計的最常用方法&#xff0c;能夠有效降低動態功耗。在實際使用中&#xff0c;一般用ICG&#xff08;集成門控時鐘單元&#xff09;來完成clock gating。ICG電路和時序如下&#xff1a; 通常來說&#xff0c;工藝庫已經集成了ICG&#xff0c;在做門控…

U-boot中TFTP 解釋

http://www.cnblogs.com/heaad/archive/2009/08/10/1542538.html

BlackHat Arsenal USA 2018 ToolsWatch黑客工具庫

原文鏈接&#xff1a;https://medium.com/hack-with-github/black-hat-arsenal-usa-2018-the-w0w-lineup-7de9b6d32796 Black Hat Arsenal USA 2018?—?The w0w lineup After the huge success of Black Hat Arsenal USA 2017, toolswatch has now announced the list of too…

SOA是什么

SOA是什么&#xff1f; SOA是面向服務的架構&#xff0c;是一個組件模型&#xff0c;它將應用程序的不同功能單元&#xff08;稱為服務&#xff09;通過這些服務之間定義良好的接口和契約聯系起來。接口是采用中立的方式進行定義的&#xff0c;它獨立于實現服務的硬件平臺、操作…

redis 優化

系統優化echo "vm.overcommit_memory1" > /etc/sysctl.conf 0&#xff0c; 表示內核將檢查是否有足夠的可用內存供應用進程使用&#xff1b;如果有足夠的可用內存&#xff0c;內存申請允許&#xff1b;否則&#xff0c;內存申請失敗&#xff0c;并把錯誤返回給應…

IC設計常見設計思想

速度與面積互換原則 所謂速度&#xff0c;是指整個工程穩定運行所能夠達到的最高時鐘頻率&#xff0c;它不僅和電路內部各個寄存器的建立時間、保持時間以及外部器件接口的各種時序要求有關&#xff0c;而且還和兩個緊鄰的寄存器間的邏輯延時&#xff0c;走線延時有關。所謂面…

DM365 u-boot啟動分析

http://www.61ic.com/Article/DaVinci/DM644X/201009/27429.html

(十三)Hibernate高級配置

配置數據庫連接池 配置C3P0連接池。先導入c3p0包。然后在hibernate.cfg.xml文件中 &#xff0c;使用下面代碼配置連接池<property name"hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>可以通過下面的…

eclipse中如何配置tomcat

1.打開eclipse上面的Windows選項&#xff0c;選擇Preferences>Server>Runtime Environments>Add 2.選擇你電腦中安裝的tomcat的版本我的是8所以我選的是Apache Tomcat v8.0 3,Next>Browse選擇Tomcat的安裝目錄&#xff0c;選擇jdk 4.Finish>OK tomcat配置完成。…

jsp調試小技巧

console.log($("#toolbar")); 打印對象可知道這個對象的參數信息轉載于:https://www.cnblogs.com/chenweida/p/6149342.html

數字IC驗證學習(一)

一、數據類型 1、logic logic類型只能有一個驅動。使用wire和reg的地方均可使用logic&#xff0c;但如雙向總線等有多個驅動的地方&#xff0c;則不可使用logic。 2、二值邏輯 對于二值邏輯變量與DUT中的四值邏輯變量連接時&#xff0c;如果DUT中產生了X和Z&#xff0c;會被…

SecureCRT 配置文件中 找密碼

打開本地電腦如下路徑 C:\Users\XXX\AppData\Roaming\VanDyke\Config\Sessions 找到配置文件。 運行命令&#xff1a;python SecureCRTDecrypt.py [配置文件名稱] 例如&#xff1a;python SecureCRTDecrypt.py 192.168.1.249.ini ssh root192.168.1.249 # 123456 即可得到密…

刷題比賽

題目描述 給你四個數組A,B,C,D. 給出每個數組的初始值A[1] 1, B[1] 1, C[1] 1, D[1] 1 , A[2] 3, B[2] 3, C[2] 3, D[2] 3; 有以下的遞推公式: (1) a[k2]p* a[k1]qa[k]b[k1]c[k1]r k^2t * k1d[k]; (2)b[k2]u* b[k1]vb[k]a[k1]c[k1]w^kd[k]; (3)c[k2]x c[k1]yc[k]a[k1]b[…

自動化測試用例設計原則

自動化測試用例設計原則&#xff1a;每一個用例 都是一個閉合的業務操作。用例之間要保持獨立 &#xff0c;不要有操作上的依賴關系&#xff0c;就算有也是測試數據上的依賴。第二個用例 依賴第一個用例產生的數據。轉載于:https://www.cnblogs.com/yyjiangnan/p/6149430.html

MII/MDIO接口詳解

MII/MDIO接口詳解 http://dpinglee.blog.163.com/blog/static/144097753201041131115262/

T24412 Cup#182-3 洞穴之旅

弱連通模板題&#xff0c;不過還是不會。。。 這道題在POJ2762有&#xff0c;這個出題人直接翻譯弄過來了。。。 弱連通的定義是&#xff1a;從u能到達v或從v能到達u&#xff0c;則u和v這兩個點弱連通。 顯然如果是強連通分量就一定是弱連通分量啦&#xff0c;所以可以直接縮點…

PCB相關的基礎知識

http://www.elecfans.com/article/89/92/2017/20170425510728.html轉載于:https://www.cnblogs.com/jackn-crazy/p/7300228.html