外觀模式: 又稱門面模式: 外觀Facade為子系統的一組接口提供一個一致界面,使得這組子系統易于使用(通過引入一個新的外觀角色降低原系統復雜度,同時降低客戶類與子系統的耦合度).
實現
案例需求: 租房
有過自己找房租房經歷的同學能夠體會得到找房是件很痛苦的事, 不光要挨個小區跑而且還要跟(二)房東討價還價. 于是后來學聰明了, 不再自己挨門挨戶的磨嘴皮子, 而是直接找像鏈家、我愛我家這樣的房屋中介, 他們手上握有一定的房源, 我們只需付給他們一筆傭金, 他們便可以代我們跟房東講價, 而且他們大都很專業, 省時間又省錢. 此時房屋中介就是一個外觀Facade, 而房屋的出租戶就是子系統SubSystem:
Facade
外觀類: 知道哪些子系統負責處理請求, 將客戶的請求代理給適當的子系統對象:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public class MediumFacade { private CuiYuanApartment cuiyuan; private XiXiApartment xixi; private XiHuApartment xihu; public MediumFacade() { cuiyuan = new CuiYuanApartment( "翠苑小區" , 900 , 1 ); xixi = new XiXiApartment( "西溪花園" , 1200 , 1 ); xihu = new XiHuApartment( "西湖小區" , 2600 , 1 ); } public void rentingHouse( double price) { // 價錢合適而且有房可組 if (price >= cuiyuan.getPrice() && cuiyuan.getStatus() != 0 ) { System.out.println( "預訂" + cuiyuan.getLocation()); cuiyuan.setStatus( 0 ); } else if (price >= xixi.getPrice() && xixi.getStatus() != 0 ) { System.out.println( "預訂" + xixi.getLocation()); xixi.setStatus( 0 ); } else if (price >= xihu.getPrice() && xihu.getStatus() != 0 ) { System.out.println( "預訂" + xihu.getLocation()); xihu.setStatus( 0 ); } else { System.out.println( "出價太低/沒有房源 ..." ); } } } |
SubSystem
子系統集合: 實現子系統功能, 處理Facade對象指派的任務(注意子系統內沒有任何Facade信息,即沒有任何Facade對象引用):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
/** * @author jifang * @since 16/8/23 上午10:12. */ public class XiHuApartment { private String location; private double price; private int status; public XiHuApartment(String location, double price, int status) { this .location = location; this .price = price; this .status = status; } public String getLocation() { return location; } public double getPrice() { return price; } public int getStatus() { return status; } public void setStatus( int status) { this .status = status; } } class XiXiApartment { private String location; private double price; private int status; public XiXiApartment(String location, double price, int status) { this .location = location; this .price = price; this .status = status; } public String getLocation() { return location; } public double getPrice() { return price; } public int getStatus() { return status; } public void setStatus( int status) { this .status = status; } } class CuiYuanApartment { private String location; private double price; private int status; public CuiYuanApartment(String location, double price, int status) { this .location = location; this .price = price; this .status = status; } public String getLocation() { return location; } public double getPrice() { return price; } public int getStatus() { return status; } public void setStatus( int status) { this .status = status; } } |
Client
這樣, Client只需跟一個房屋中介聯系并給出我們的報價, 他們便會幫我們聯系所有符合的房東:
1
2
3
4
5
6
7
8
|
public class Client { @Test public void client() { MediumFacade facade = new MediumFacade(); facade.rentingHouse( 800 ); } } |
小結
有過面向對象開發經驗的同學 即使沒有聽說過外觀模式, 也完全有可能使用過他, 因為他完美的體現了依賴倒轉原則和迪米特法則的思想, 是非常常用的模式之一.
使用
首先 在設計初期, 應該有意識的進行層次分離, 比如經典的三層架構, 層與層之間建立Facade, 這樣可以為復雜的子系統提供一個簡單的接口, 使耦合度大大降低.
其次 在開發階段, 子系統往往因為不斷的重構而變得越來越復雜, 增加Facade可以提供一個簡單的接口, 減少模塊間依賴.
第三 在維護一個遺留系統時, 可能這個系統已經非常難以維護和擴展了, 但因為它包含非常重要的功能, 新的需求必須依賴它, 此時可以為新系統開發一個Facade, 為設計粗糙或高復雜度的遺留代碼提供一個的比較清晰簡單的接口, 讓新系統與Facade交互, 而Facade與遺留代碼交互所有繁雜的工作.
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。