外观模式: 又称门面模式: 外观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与遗留代码交互所有繁杂的工作.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。