我正在参与掘金创作者训练营第4期,点击了解活动详情,一起学习吧!
白话一下
话说毕业后在职场打拼多年的郭靖,在襄阳按揭买的房终于交房了,想着和女朋友黄蓉在新房里完婚的场景,内心激动万分。突然想起毛坯房还没装修不能入住,不由从梦中惊醒。远房表叔柯镇恶曾经干过装修队,于是郭靖马上拨通了他的电话。柯镇恶告诉了他很多门道,让他自己去买材料,再找几个装修工人来施工,这样可以省不少钱,郭靖点头称是。
到了周末郭靖拉上女朋友,兴高采烈直奔建材市场而去。然而逛了一天下来,发现要买的材料种类太多,价格也高低不一,要买齐所有材料,对一个装修小白来说就已经很不容易了,更别说还想要价廉物美了。两人愁容满面的走出了建材市场。
正在门口苦恼的郭靖,眼前走过一个熟悉的身影,这不是多年不见的发小杨康吗?他一把叫住杨康,一番寒暄之后,发现杨康开了一家装修公司,据杨康说可以为客户提供一站式服务,正好可以解决郭靖的苦恼。最终郭靖决定把装修的事委托给杨康来办。
杨康请公司首席设计师穆念慈定制了图纸,又从建材商欧阳克等处进了上好的材料,最后请了梅超风等手艺精湛的老师傅,为郭靖的新房装修了一番。郭靖从头至尾只和杨康打交道,省却了不少烦恼。最后,装修如期完工,郭靖黄蓉也如期完婚,两人从此过上了幸福快乐的生活。
说正经的
什么是外观模式?
外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。
从故事中我们很容易发现,外观模式的目的是降低系统复杂度,从而提高客户端调用的便捷性。它非常符合迪米特法则,即一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解,只和朋友通信,不和陌生人说话。郭靖只要和杨康说话,根本不用管他背后的梅超风、欧阳克之类的。
UML类图如下:
优点
- 对客户来说,使用变得更加简便,客户端的代码也更简单。自从遇上杨康之后,郭靖从此省心了不少。
- 客户端和子系统之间实现了松耦合关系。如果有一天梅超风不干了,杨康只需要请另一位师傅丘处机来施工,不会影响到郭靖。
缺点
- 外观模式最大的缺点在于违背了“开闭原则”,当增加新的子系统或者移除子系统时需要修改外观类。可以通过引入抽象外观类在一定程度上解决该问题,客户端针对抽象外观类进行编程。
适用场景
当系统非常复杂或难以理解时,开发人员通常会引入外观模式,因为系统有许多相互依赖的类,或者因为它的源代码不可用。这种模式隐藏了子系统的复杂性,并为客户端提供了更简单的接口。
代码演示
以上面UML类图为例,Java
的代码实现如下:
public class Class1 {
public void doStuff(Class2 c2) {
// ...
}
public X getX() {
return this.x;
}
}
public class Class2 {
// ...
}
public class Class3 {
public void setX(X x) {
// ...
}
public Y getY(){
return this.y;
}
}
public class Facade {
public Y doSomething() {
Class1 c1 = new Class1();
Class2 c2 = new Class2();
Class3 c3 = new Class3();
c1.doStuff(c2);
c3.setX(c1.getX());
return c3.getY();
}
}
public class Client1 {
void doIt() {
// ...
Facade facade = new Facade();
facade.doSomething();
}
}