设计模式(十)--外观模式

目录

外观模式(Facade Pattern)

外观模式的关键组成部分

外观模式的应用场景

外观模式的实现步骤

外观模式的示例

步骤1:定义子系统类

步骤2:实现外观类

步骤3:客户端代码

运行结果

解释

外观模式的优点

外观模式的缺点

总结


外观模式(Facade Pattern)

外观模式是一种结构型设计模式,它为子系统中的一组接口提供一个一致的界面。外观模式定义了一个高层接口,使得子系统更容易被访问。通过使用外观模式,客户端不需要与子系统的每一个类打交道,而是通过一个简单的接口来访问整个子系统。

外观模式的关键组成部分

  1. 子系统类(Subsystem Classes):子系统类是外观类所调用的实际工作类。
  2. 外观类(Facade):提供了一个高层次的接口,使得子系统更容易被访问。

外观模式的应用场景

外观模式适用于以下情况:

  • 子系统有太多接口,使得客户端很难使用。
  • 提供一个统一的入口点来访问子系统的功能。
  • 简化复杂的子系统,提供一个简化的接口。

外观模式的实现步骤

  1. 定义子系统类。
  2. 实现外观类,并提供一个简单的方法来访问子系统的功能。
  3. 客户端通过外观类来访问子系统。

外观模式的示例

假设我们正在开发一个多媒体播放器应用程序,该应用程序需要从磁盘加载音频文件、解码音频文件、并将解码后的音频播放出来。这些操作涉及多个子系统,包括音频加载器、音频解码器和音频播放器。我们可以使用外观模式来简化这些子系统的使用。

步骤1:定义子系统类
 

c

深色版本

1#include <stdio.h>
2#include <stdlib.h>
3
4// 音频加载器子系统
5typedef struct AudioLoader {
6    void (*loadAudioFile)(const char *file);
7} AudioLoader;
8
9void audioLoaderLoadAudioFile(const char *file) {
10    printf("Loading audio file: %s\n", file);
11}
12
13AudioLoader* createAudioLoader() {
14    AudioLoader *loader = (AudioLoader *)malloc(sizeof(AudioLoader));
15    loader->loadAudioFile = audioLoaderLoadAudioFile;
16    return loader;
17}
18
19// 音频解码器子系统
20typedef struct AudioDecoder {
21    void (*decodeAudio)();
22} AudioDecoder;
23
24void audioDecoderDecodeAudio() {
25    printf("Decoding audio...\n");
26}
27
28AudioDecoder* createAudioDecoder() {
29    AudioDecoder *decoder = (AudioDecoder *)malloc(sizeof(AudioDecoder));
30    decoder->decodeAudio = audioDecoderDecodeAudio;
31    return decoder;
32}
33
34// 音频播放器子系统
35typedef struct AudioPlayer {
36    void (*playAudio)();
37} AudioPlayer;
38
39void audioPlayerPlayAudio() {
40    printf("Playing audio...\n");
41}
42
43AudioPlayer* createAudioPlayer() {
44    AudioPlayer *player = (AudioPlayer *)malloc(sizeof(AudioPlayer));
45    player->playAudio = audioPlayerPlayAudio;
46    return player;
47}
步骤2:实现外观类
 

c

深色版本

1// 多媒体播放器外观类
2typedef struct MediaPlayerFacade {
3    AudioLoader *loader;
4    AudioDecoder *decoder;
5    AudioPlayer *player;
6    void (*playAudioFile)(const char *file);
7} MediaPlayerFacade;
8
9void mediaPlayerFacadePlayAudioFile(MediaPlayerFacade *facade, const char *file) {
10    facade->loader->loadAudioFile(file);
11    facade->decoder->decodeAudio();
12    facade->player->playAudio();
13}
14
15MediaPlayerFacade* createMediaPlayerFacade() {
16    MediaPlayerFacade *facade = (MediaPlayerFacade *)malloc(sizeof(MediaPlayerFacade));
17    facade->loader = createAudioLoader();
18    facade->decoder = createAudioDecoder();
19    facade->player = createAudioPlayer();
20    facade->playAudioFile = mediaPlayerFacadePlayAudioFile;
21    return facade;
22}
23
24void destroyMediaPlayerFacade(MediaPlayerFacade *facade) {
25    free(facade->loader);
26    free(facade->decoder);
27    free(facade->player);
28    free(facade);
29}
步骤3:客户端代码
 

c

深色版本

1int main() {
2    MediaPlayerFacade *mediaPlayer = createMediaPlayerFacade();
3
4    mediaPlayer->playAudioFile(mediaPlayer, "song.mp3");
5
6    destroyMediaPlayerFacade(mediaPlayer);
7
8    return 0;
9}

运行结果

当你运行上述 main 函数时,你会看到以下输出:

 

深色版本

1Loading audio file: song.mp3
2Decoding audio...
3Playing audio...

解释

在这个例子中,我们定义了三个子系统类:AudioLoaderAudioDecoderAudioPlayer。这些类分别代表了加载音频文件、解码音频文件和播放音频的功能。我们通过 MediaPlayerFacade 类来提供一个统一的接口 playAudioFile,客户端只需要调用这个方法就可以完成音频文件的加载、解码和播放。

外观模式的优点

  1. 简化接口:外观模式通过提供一个简单的接口来访问子系统的功能,使得客户端代码更加简洁。
  2. 降低依赖性:客户端不需要知道子系统的具体实现细节,只需要通过外观类来访问子系统。
  3. 易于维护:子系统的更改不会影响到客户端,只要外观类的接口不变。

外观模式的缺点

  1. 增加复杂性:虽然外观模式简化了客户端的使用,但是增加了系统的复杂性,特别是在大型系统中,可能需要多个外观类来简化不同的子系统。
  2. 过度抽象:有时候,过度使用外观模式可能会导致过度抽象的问题,使得系统设计变得不够灵活。

总结

外观模式通过提供一个统一的接口来简化子系统的使用,适用于需要简化复杂子系统接口的场景。在设计系统时,如果发现子系统的接口过于复杂,难以使用,可以考虑使用外观模式来简化接口,提高代码的可读性和可维护性。

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值