类图: 外观设计模式类图
一.什么是外观设计模式?
外观设计模式(Facade Pattern)是一种结构型设计模式,通过为子系统中的一组接口提供一个一致的外部接口,简化客户端的使用。它将复杂的子系统封装起来,向客户端提供一个统一的、简单的访问方式。
核心思想:为子系统创建一个高级接口,隐藏其复杂性,让客户端与子系统交互变得简单。
二.外观设计模式的特点
- 简化客户端接口:通过统一的外观类减少直接访问复杂子系统的需求。
- 解耦性:客户端与子系统之间通过外观类交互,从而降低了耦合度。
- 灵活性:在不改变子系统的前提下,可以随时调整外观类的功能。
三.外观设计模式的结构
- Facade(外观类):为客户端提供统一接口,协调子系统的功能。
- Subsystems(子系统):一组复杂的子系统,执行实际的业务逻辑,对外部隐藏实现细节。
- Client(客户端):通过外观类调用子系统功能,而无需直接与子系统交互。
四.外观设计模式的优缺点
- 优点:
- 降低客户端与子系统之间的耦合性。
- 提高代码可读性和易用性,简化复杂子系统的调用过程。
- 为系统增加新的外观类而不会影响子系统代码。
- 缺点:
- 外观类可能成为“上帝类”,过多依赖外观类可能导致其职责过于繁重。
- 增加系统复杂性:如果过度设计外观层,可能导致代码冗余。
五.外观设计模式的 C++ 实现
以下代码展示一个家庭影院系统的例子,外观类 HomeTheaterFacade 将隐藏复杂的子系统操作。
#include <iostream>
#include <string>
using namespace std;// 子系统1:音响系统
class SoundSystem {
public:void On() { cout << "Sound System: On\n"; }void Off() { cout << "Sound System: Off\n"; }void SetVolume(int level) { cout << "Sound System: Volume set to " << level << endl; }
};// 子系统2:投影仪
class Projector {
public:void On() { cout << "Projector: On\n"; }void Off() { cout << "Projector: Off\n"; }void SetInput(const string& input) { cout << "Projector: Input set to " << input << endl; }
};// 子系统3:播放器
class MediaPlayer {
public:void On() { cout << "Media Player: On\n"; }void Off() { cout << "Media Player: Off\n"; }void Play(const string& movie) { cout << "Media Player: Playing movie \"" << movie << "\"\n"; }void Stop() { cout << "Media Player: Stopped\n"; }
};// 外观类:家庭影院
class HomeTheaterFacade {
private:SoundSystem sound;Projector projector;MediaPlayer player;public:void WatchMovie(const string& movie) {cout << "Setting up movie theater...\n";sound.On();sound.SetVolume(10);projector.On();projector.SetInput("HDMI");player.On();player.Play(movie);cout << "Movie is ready to watch!\n";}void EndMovie() {cout << "Shutting down movie theater...\n";player.Stop();player.Off();projector.Off();sound.Off();cout << "Goodbye!\n";}
};// 主函数
int main() {HomeTheaterFacade homeTheater;homeTheater.WatchMovie("Inception");homeTheater.EndMovie();return 0;
}
JAVA__101">六.外观设计模式的 JAVA 实现
// 子系统1:音响系统
class SoundSystem {public void on() {System.out.println("Sound System: On");}public void off() {System.out.println("Sound System: Off");}public void setVolume(int level) {System.out.println("Sound System: Volume set to " + level);}
}// 子系统2:投影仪
class Projector {public void on() {System.out.println("Projector: On");}public void off() {System.out.println("Projector: Off");}public void setInput(String input) {System.out.println("Projector: Input set to " + input);}
}// 子系统3:播放器
class MediaPlayer {public void on() {System.out.println("Media Player: On");}public void off() {System.out.println("Media Player: Off");}public void play(String movie) {System.out.println("Media Player: Playing movie \"" + movie + "\"");}public void stop() {System.out.println("Media Player: Stopped");}
}// 外观类:家庭影院
class HomeTheaterFacade {private SoundSystem sound = new SoundSystem();private Projector projector = new Projector();private MediaPlayer player = new MediaPlayer();public void watchMovie(String movie) {System.out.println("Setting up movie theater...");sound.on();sound.setVolume(10);projector.on();projector.setInput("HDMI");player.on();player.play(movie);System.out.println("Movie is ready to watch!");}public void endMovie() {System.out.println("Shutting down movie theater...");player.stop();player.off();projector.off();sound.off();System.out.println("Goodbye!");}
}// 主函数
public class FacadePatternDemo {public static void main(String[] args) {HomeTheaterFacade homeTheater = new HomeTheaterFacade();homeTheater.watchMovie("Inception");homeTheater.endMovie();}
}
七.代码解析
- 子系统:
- SoundSystem:控制音响的开关和音量。
- Projector:负责控制投影仪的开关和输入源。
- MediaPlayer:负责播放和停止电影。
- 外观类 HomeTheaterFacade:
- 通过组合子系统对象来封装复杂逻辑。
- 提供了两个高层次接口:WatchMovie 和 EndMovie,分别用于启动和关闭家庭影院。
- 客户端:
- 客户端直接调用外观类的方法,无需了解子系统的具体操作流程。
八.总结
外观模式通过封装复杂子系统的调用细节,为客户端提供了简单易用的接口。它在需要对复杂系统进行高层次封装时非常有用,但要注意外观类的职责划分,避免其承担过多功能而导致维护困难。
应用场景:
- 跨平台开发:隐藏不同平台的底层实现,为上层应用提供一致接口。
- 第三方库封装:通过外观类封装复杂的库调用,使得库更易用。
- 复杂系统简化:将多个模块组合起来,为外部提供一个简单接口。