forked from ascoders/weekly
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
99 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
# Facade(外观模式) | ||
|
||
Facade(外观模式)属于结构型模式,是一种日常开发中经常被使用到的设计模式。 | ||
|
||
**意图:为子系统中的一组接口提供一个一致的界面,Facade 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。** | ||
|
||
## 举例子 | ||
|
||
如果看不懂上面的意图介绍,没有关系,设计模式需要在日常工作里用起来,结合例子可以加深你的理解,下面我准备了三个例子,让你体会什么场景下会用到这种设计模式。 | ||
|
||
## 意图解释 | ||
|
||
### 图书管理员 | ||
|
||
图书馆是一个非常复杂的系统,虽然图书按照一定规则摆放,但也只有内部人员比较清楚,作为一位初次来的访客,想要快速找到一本书,最好的办法是直接问图书管理员,而不是先了解这个图书馆的设计,因为你可能要来回在各个楼宇间奔走,借书的流程可能也比较长。 | ||
|
||
图书管理员就起到了简化图书馆子系统复杂度的作用,我们只要凡事询问图书管理员即可,而不需要关心他是如何与图书馆内部系统打交道的。 | ||
|
||
### 最多跑一次便民服务 | ||
|
||
浙江省推出的最多跑一次服务非常方便,很多办事流程都简化了,无论是证件办理还是业务受理,几乎只要跑一次,而必须要持续几天的流程也会通过手机短信或者 App 操作完成后续流程。 | ||
|
||
这就相当于外观模式,因为政府系统内部的办事流程可能没有太大变化,但通过抽象出 Facade(外观),让普通市民可以直接与便民办事处连接,而不需要在车管所与驾校之间来回奔波,背后的事情没有少,只是便民办事处帮你做了。 | ||
|
||
### Iphone 快捷指令功能 | ||
|
||
手机的 App 非常多,而我们需要了解每个功能在哪个 App 上才能运用自如,而快捷指令功能可以将 App 的某些功能单独提取出来,形成一套新的功能组,我们可以只接触到 “拍照” “付款” “计算”,而不用管背后是调用了支付宝还是微信、系统内置摄像机还是其他摄像 App,也不用关心这个 App 内部功能的入口在哪里,这些对接都在快接指令中自动完成。 | ||
|
||
快捷指令也是一种外观模式。 | ||
|
||
## 意图解释 | ||
|
||
**意图:为子系统中的一组接口提供一个一致的界面,Facade 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。** | ||
|
||
为降低一个拥有多个接口的子系统内部复杂性,我们需要一个外观来屏蔽内部的复杂性,因此外观模式就是定义一个高层接口,这个接口直连子系统的内部实现,但调用这个高层接口的人不需要关心子系统内部的实现,这样,对于不想了解子系统内部实现的人来说,提高了易用度。 | ||
|
||
当然如果想要深度定制,就可以绕过外观模式,直接使用子系统提供的类,所以说并不是有了外观模式就必须通过外观调用,而是根据实际需要判断使用哪种调用方式。 | ||
|
||
## 结构图 | ||
|
||
<img width=600 src="https://img.alicdn.com/tfs/TB1j9gZ3.T1gK0jSZFrXXcNCXXa-1082-412.png"> | ||
|
||
可以看到,Facade 直接指向子系统中的类,**而子系统的类不会反向指向 Facade**。 | ||
|
||
## 代码例子 | ||
|
||
下面例子使用 typescript 编写。 | ||
|
||
```typescript | ||
// 假设一个子系统是三个类结合使用的,为了抽象而解耦开了 | ||
class A { | ||
constructor(b: B) { | ||
this.b = b | ||
} | ||
} | ||
|
||
class B { | ||
constructor(c: C) { | ||
this.c = c | ||
} | ||
} | ||
|
||
class C { | ||
|
||
} | ||
|
||
// 它们组合成了一种常用功能,我们可以使用外观模式屏蔽子类的细节直接使用 | ||
class Compile { | ||
public run() { | ||
const parser = new A(new B(new C)) | ||
parser.run() | ||
} | ||
} | ||
|
||
const compile = new Compile() | ||
compile.run() | ||
``` | ||
|
||
这样我们只要知道 `Compile` 类就可以了,而不需要了解背后的 `A` `B` `C` 以及其组合关系。 | ||
|
||
## 弊端 | ||
|
||
外观模式并不适合于所有场景,当子系统足够易用时,再使用外观模式就是画蛇添足。 | ||
|
||
另外,当系统难以抽象出通用功能时,外观模式的设计可能也无所适从,因为设计的高层接口可能适用范围很窄,此时外观模式的意义就比较小。 | ||
|
||
## 总结 | ||
|
||
其实抽象工厂模式也可以代替外观模式,来实现隐藏子类具体实现的效果,但外观模式描述更具有通用性。 | ||
|
||
> 讨论地址是:[精读《设计模式 - Facade 外观模式》· Issue #286 · dt-fe/weekly](https://github.com/dt-fe/weekly/issues/288) | ||
**如果你想参与讨论,请 [点击这里](https://github.com/dt-fe/weekly),每周都有新的主题,周末或周一发布。前端精读 - 帮你筛选靠谱的内容。** | ||
|
||
> 关注 **前端精读微信公众号** | ||
<img width=200 src="https://img.alicdn.com/tfs/TB165W0MCzqK1RjSZFLXXcn2XXa-258-258.jpg"> | ||
|
||
> 版权声明:自由转载-非商用-非衍生-保持署名([创意共享 3.0 许可证](https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh)) |