一、简介
外观模式(Facade Pattern)是一种结构型设计模式,提供了一个统一的接口,用于访问子系统中的一组接口。这个模式隐藏了子系统的复杂性,并为客户端提供了一个更简单的接口,使得客户端与子系统之间的通信更加简单和直接。
外观模式的主要目的是降低系统的复杂性,为客户端提供一个更加简化的接口,使得客户端不需要了解系统的内部结构和实现细节,只需通过外观类进行操作即可。在外观模式中,通常有以下几个角色:
-
Facade(外观): 外观类是客户端访问子系统的入口。它将客户端的请求委派给子系统中的相应对象,协调子系统对象完成任务。
-
Subsystem(子系统): 子系统是具体的功能模块或者类群。它们实现了系统的各种功能,但是对于客户端来说,这些功能的实现细节是透明的。
外观模式可以帮助解耦客户端和子系统之间的依赖关系,降低了客户端与子系统之间的耦合性,同时也提高了系统的可维护性和灵活性。通过提供一个简化的接口,外观模式使得系统更易于使用和理解。
二、外观模式
2.1、子系统
当设计一个家庭影院系统时,可以使用外观模式来简化各个子系统(如投影仪、音响、灯光等)的操作
// 子系统:投影仪
public class Projector {
public void on() {
System.out.println("打开投影仪");
}
public void off() {
System.out.println("关闭投影仪");
}
public void setInput(String input) {
System.out.println("投影仪准备播放:" + input);
}
}
// 子系统:音响
class SoundSystem {
public void on() {
System.out.println("打开声音");
}
public void off() {
System.out.println("关闭声音");
}
public void setVolume(int volume) {
System.out.println("音量设置为: " + volume);
}
}
// 子系统:灯光
public class Lights {
public void dim() {
System.out.println("关闭灯光");
}
public void brighten() {
System.out.println("打开灯光");
}
}
2.2、外观类
// 外观类:家庭影院外观
public class HomeTheaterFacade {
private Projector projector;
private SoundSystem soundSystem;
private Lights lights;
public HomeTheaterFacade(Projector projector, SoundSystem soundSystem, Lights lights) {
this.projector = projector;
this.soundSystem = soundSystem;
this.lights = lights;
}
public void watchMovie(String movie) {
System.out.println("准备看家庭影院...");
lights.dim();
projector.on();
projector.setInput(movie);
soundSystem.on();
soundSystem.setVolume(16);
}
public void endMovie() {
System.out.println("关闭家庭影院...");
soundSystem.off();
projector.off();
lights.brighten();
}
}
2.3、使用
// 测试类
public class FacadeHomeTheaterExample {
public static void main(String[] args) {
Projector projector = new Projector();
SoundSystem soundSystem = new SoundSystem();
Lights lights = new Lights();
HomeTheaterFacade homeTheater = new HomeTheaterFacade(projector, soundSystem, lights);
// 看电影
homeTheater.watchMovie("战狼");
// 结束电影
homeTheater.endMovie();
}
}
运行结果:
准备看家庭影院...
关闭灯光
打开投影仪
投影仪准备播放:战狼
打开声音
音量设置为: 16
关闭家庭影院...
关闭声音
关闭投影仪
打开灯光
在这个示例中,Projector、SoundSystem、Lights 分别表示家庭影院的投影仪、音响和灯光,HomeTheaterFacade 是外观类。客户端通过调用外观类的方法来实现整个家庭影院系统的控制,而不需要直接与各个子系统进行交互。外观模式将各个子系统的操作封装起来,使得客户端更加简单地控制家庭影院。
三、优点与缺点
外观模式是一种有用的设计模式,它有一些优点和缺点。
优点:
- 简化接口: 外观模式为复杂系统提供了一个简单的接口,隐藏了系统的复杂性,使得客户端更容易使用系统。
- 降低耦合性: 外观模式可以降低客户端与子系统之间的耦合度,因为客户端只需与外观类进行交互,而不需要直接与多个子系统交互。
- 更好的封装性: 外观模式能够将系统的内部细节封装起来,避免暴露给客户端,提高了系统的安全性和可靠性。
- 易于使用: 对于客户端来说,使用外观模式更加直观和易于理解,不需要了解系统的内部结构和实现细节。
缺点:
- 不符合开闭原则: 在需要新增或修改子系统的功能时,可能需要修改外观类,这可能违反了开闭原则,导致外观类的修改。
- 可能引入单点故障: 如果外观类出现问题,可能影响整个系统,因为外观类控制了整个子系统的访问。
- 可能增加系统复杂性: 如果外观类设计不当,可能会导致外观类本身也变得复杂,难以维护和理解。
总的来说,外观模式适合在需要简化客户端与复杂系统之间交互的场景下使用,但需要注意合理设计外观类,避免引入过度复杂性和耦合度。