摘要:本文深入浅出的讲述了设计模式中的外观模式
,
并给出了简单的示例
,
例子浅显易懂
,
并附带源代码。
外观模式属于结构型模式,其意图是为子系统中的一组接口提供一个一致的界面,
Façade
模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。在项目设计中,把一个系统划分成为若干个子系统由利于降低系统的复杂性,一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小,达到该目标的途径之一就是引入一个外观对象,它为子系统中较一般的设施提供了一个单一而简单的界面。
实用性:
l
当需要为一个复杂子系统提供一个简单的接口时。子系统往往因为不断演化而变得越来越复杂,大多是模式使用时都会产生更多更小的类,这使得子系统更具有可重用性,也更容易对子系统进行订制,但是这也给那些不需要订制子系统的用户带来一些使用上的困难。
l
客户程序与抽象类的实现部分之间存在很大的依赖性,引入
façade
将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
l
当你需要构建一个层次结构的子系统时,使用
Façade
模式定义子系统中每层的入口点,如果子系统间是相互依赖的,你可以让他们通过
Facade
进行通讯,从而简化他们之间的依赖关系。
例如在一个泡茶的过程中,需要作如下的工作:烧开水,准备茶叶,把茶叶放在被子里,把烧开的水放到茶杯中,只有经过这些过程之后才能泡出好的茶叶来。这是一个常用的步骤,
80%
的泡茶步骤都是这个样子的,可以把这些动作串联起来,形成一个整体的步骤,就是
MakeACuppa()
,这样在调用步方法时也比较方便。这便是外观模式,里面的细节被屏蔽掉了。当然如果想更详细的控制每个步骤地过程,也允许进行相应的控制,但是必须自己创建类。
图
1
参与者:
Façade(DacadeCuppaMaker):
知道那些子系统类负责处理请求;将客户的请求代理给适当的子系统。
SubSystem classes
(
water
,
Teabag
):实现自系统的功能,处理由
Façade
对象指派的任务,没有
Facade
的任何相关信息,即没有指向
Façade
的指针。
他们之间的协作关系是:客户程序通过发送请求给
Façade
的方式与子系统通讯,
Facade
将这些消息转发给适当的子系统对象,尽管是子系统的有关对象在做实际工作
,
但
Façade
模式本身也必须将它的接口转换成子系统的接口。使用
façade
的客户程序不需要直接访问子系统对象。
使用
Façade
模式有下面一些优点:
1.
他对客户屏蔽子系统组件,因而减少了客户处理的对象的树木并使得子系统使用起来更加方便。
2.
实现了自系统与客户之间的松散耦合关系,而自系统内部的功能组件往往是紧耦合的。松耦合关系使得自系统的组件变化不会影响到他的客户。
3.
如果需要他们不限制他们使用子系统类。
在本系统中,
Teacup
使用
water
和
TeaBag
泡一杯茶水,泡茶的过程比较复杂,这相当于一个子系统,在这个子系统中泡茶的每一个步骤都是紧密相连的,如果使用每个子类按照泡茶的步骤一步步地走下来也可以达到目的,但是在这个过程中需要创建子类,调用子类的方法,或者检测子类的变量,而在客户端大部分的操作都是使用一样的代码,把这些一样的代码抽取出来形成一个能完成一特定功能的类,便形成了
Façade
模式的代码。使用了
Façade
模式就使得这些操作聚合在一起,方便客户端调用。
相应的代码:
Water
代码:
package
facade;
public
class
Water{
boolean
waterIsBoiling
;
public
Water(){
setWaterIsBoiling(
false
);
System.
out
.println(
"
纯净的水准备好了
"
);
}
public
void
setWaterIsBoiling(
boolean
isWaterBoiling){
waterIsBoiling
= isWaterBoiling;
}
public
boolean
getWaterIsBoiling(){
return
waterIsBoiling
;
}
public
void
boilFacadeWater(){
setWaterIsBoiling(
true
);
System.
out
.println(
"
水在沸腾
"
);
}
}
TeaBag
代码:
package
facade;
public
class
TeaBag{
public
TeaBag(){
System.
out
.println(
"
清香的茶包准备好了
!"
);
}
}
TeaCup
代码:
package
facade;
public
class
TeaCup{
private
boolean
teaBagIsSteeped
;
private
Water
facadeWater
;
private
TeaBag
facadeTeaBag
;
public
TeaCup(){
setTeaBagIsSteeped(
true
);
System.
out
.println(
"
茶杯准备好了
"
);
}
public
void
setTeaBagIsSteeped(
boolean
isTeaBagSteeped){
teaBagIsSteeped
=
true
;
}
public
boolean
getTeaBagIsSteeped(){
return
teaBagIsSteeped
;
}
public
void
addFacadeTeaBag(TeaBag facadeTeaBagIn){
facadeTeaBag
=
facadeTeaBagIn
;
System.
out
.println(
"
茶包放在茶杯了
"
);
}
public
void
addFacadeWater(Water facadeWaterIn){
facadeWater
= facadeWaterIn;
}
public
void
steepTeaBag(){
if
(
facadeTeaBag
!=
null
&&
facadeWater
!=
null
&&
facadeWater
.getWaterIsBoiling()){
System.
out
.println(
"
茶叶渗透到杯子中了
"
);
setTeaBagIsSteeped(
true
);
}
else
{
System.
out
.println(
"
茶叶没有渗透到杯子中
"
);
setTeaBagIsSteeped(
false
);
}
}
public
String toString(){
if
(getTeaBagIsSteeped()){
return
"
一杯又香又浓的茶冲好了
"
;
}
else
return
"
一杯又香又浓的茶冲好了
"
;
}
}
FacadeCuppaMaker
代码;
package
facade;
public
class
FacadeCuppaMaker{
private
boolean
TeaBagIsSteeped
;
public
FacadeCuppaMaker(){
System.
out
.println(
"FacadeCuppaMaker
准备好冲茶了
"
);
}
public
TeaCup makeACuppa(){
TeaCup cup =
new
TeaCup();
TeaBag teaBag=
new
TeaBag();
Water water =
new
Water();
cup.addFacadeTeaBag(teaBag);
water.boilFacadeWater();
cup.addFacadeWater(water);
cup.steepTeaBag();
return
cup;
}
}
Client
代码:
package
facade;
public
class
Client{
public
static
void
main(String[] args){
FacadeCuppaMaker cuppaMaker =
new
FacadeCuppaMaker();
TeaCup teaCup = cuppaMaker.makeACuppa();
System.
out
.println(teaCup);
}
}
总结:
外观模式的主要用途就是为子系统的复杂处理过程提供方便的调用方法,使得子系统更加容易被使用。Façade对象通常属于Singleton模式。
本文转自凌辉博客51CTO博客,原文链接http://blog.51cto.com/tianli/36741如需转载请自行联系原作者
lili00okok