外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个统一的接口,用于访问子系统中的一组接口。外观模式通过定义一个高层接口,将子系统中的复杂逻辑封装起来,使得客户端可以通过一个简单的接口来访问整个子系统,而不需要了解子系统内部的具体实现。
外观模式主要有三个角色:
- 外观(Facade):提供了一个简单的接口,用于访问子系统中的一组接口。外观对象将客户端的请求委派给子系统中的具体对象来完成。
- 子系统(SubSystem):由多个类组成的复杂子系统,它们共同实现了外观接口定义的功能。
- 客户端(Client):通过外观接口来访问子系统,而不需要了解子系统内部的具体实现。
外观模式可以简化客户端的使用,降低了与子系统的耦合度,使得客户端代码更加清晰和易于维护。
示例:
假设我们有一个家庭影院系统,其中包含多个子系统(投影仪、音响、灯光等),现在我们希望实现一个外观类,用于控制家庭影院的启动和关闭。
// 子系统1:投影仪
class Projector {
public void turnOn() {
System.out.println("投影仪启动");
}
public void turnOff() {
System.out.println("投影仪关闭");
}
}
// 子系统2:音响
class AudioSystem {
public void turnOn() {
System.out.println("音响启动");
}
public void turnOff() {
System.out.println("音响关闭");
}
}
// 子系统3:灯光
class Lights {
public void turnOn() {
System.out.println("灯光打开");
}
public void turnOff() {
System.out.println("灯光关闭");
}
}
// 外观类:家庭影院控制器
class HomeTheaterFacade {
private Projector projector;
private AudioSystem audioSystem;
private Lights lights;
public HomeTheaterFacade(Projector projector, AudioSystem audioSystem, Lights lights) {
this.projector = projector;
this.audioSystem = audioSystem;
this.lights = lights;
}
public void startMovie() {
System.out.println("开始放电影:");
projector.turnOn();
audioSystem.turnOn();
lights.turnOff();
}
public void endMovie() {
System.out.println("电影结束:");
projector.turnOff();
audioSystem.turnOff();
lights.turnOn();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Projector projector = new Projector();
AudioSystem audioSystem = new AudioSystem();
Lights lights = new Lights();
HomeTheaterFacade homeTheater = new HomeTheaterFacade(projector, audioSystem, lights);
homeTheater.startMovie(); // 输出:开始放电影:\n投影仪启动\n音响启动\n灯光关闭
homeTheater.endMovie(); // 输出:电影结束:\n投影仪关闭\n音响关闭\n灯光打开
}
}
在上面的示例中,我们有三个子系统:投影仪、音响和灯光。然后我们定义了一个外观类HomeTheaterFacade
,它封装了对这些子系统的复杂操作,提供了简单的方法供客户端使用。客户端代码只需要通过外观类来启动和关闭家庭影院系统,而不需要关心子系统的具体实现。
通过外观模式,我们可以提供一个简单的接口给客户端来访问复杂的子系统,从而降低了客户端代码的复杂性,增加了代码的可维护性和可扩展性。