【设计模式#1】Facade设计模式(外观设计模式)的简单理解
最近接手了一个需要重构的老项目,里面大量使用了Facade设计模式来整合各个子系统的功能,故简单梳理学习一下该设计模式的概念。
外观模式(Facade Pattern)是一种结构型设计模式,它通过为复杂子系统提供一个简单的接口,从而简化客户端与子系统的交互。为了更好地理解这一模式,我们可以举一个日常生活中的例子:家庭影院系统。
家庭影院系统的外观模式
假设你有一个复杂的家庭影院系统,包含以下设备:
- DVD播放器
- 投影仪
- 环绕音响系统
- 窗帘控制系统
- 灯光控制系统
每次你要看电影时,需要执行一系列操作:
- 打开窗帘
- 关闭灯光
- 打开投影仪
- 打开DVD播放器
- 打开环绕音响系统
- 播放电影
如果没有外观模式,你需要一个一个地控制这些设备,这显然很繁琐。下面通过Java代码来展示如何使用外观模式简化这些操作。
没有外观模式的实现
class DVDPlayer {
public void on() {
System.out.println("DVD Player on");
}
public void play() {
System.out.println("DVD Player playing");
}
}
class Projector {
public void on() {
System.out.println("Projector on");
}
}
class SurroundSoundSystem {
public void on() {
System.out.println("Surround Sound System on");
}
}
class CurtainControl {
public void open() {
System.out.println("Curtain opening");
}
}
class LightControl {
public void off() {
System.out.println("Lights off");
}
}
public class HomeTheaterWithoutFacade {
public static void main(String[] args) {
DVDPlayer dvdPlayer = new DVDPlayer();
Projector projector = new Projector();
SurroundSoundSystem soundSystem = new SurroundSoundSystem();
CurtainControl curtainControl = new CurtainControl();
LightControl lightControl = new LightControl();
curtainControl.open();
lightControl.off();
projector.on();
dvdPlayer.on();
soundSystem.on();
dvdPlayer.play();
}
}
使用外观模式的实现
class DVDPlayer {
public void on() {
System.out.println("DVD Player on");
}
public void play() {
System.out.println("DVD Player playing");
}
}
class Projector {
public void on() {
System.out.println("Projector on");
}
}
class SurroundSoundSystem {
public void on() {
System.out.println("Surround Sound System on");
}
}
class CurtainControl {
public void open() {
System.out.println("Curtain opening");
}
}
class LightControl {
public void off() {
System.out.println("Lights off");
}
}
// 外观类
class HomeTheaterFacade {
private DVDPlayer dvdPlayer;
private Projector projector;
private SurroundSoundSystem soundSystem;
private CurtainControl curtainControl;
private LightControl lightControl;
public HomeTheaterFacade(DVDPlayer dvdPlayer, Projector projector, SurroundSoundSystem soundSystem, CurtainControl curtainControl, LightControl lightControl) {
this.dvdPlayer = dvdPlayer;
this.projector = projector;
this.soundSystem = soundSystem;
this.curtainControl = curtainControl;
this.lightControl = lightControl;
}
public void watchMovie() {
curtainControl.open();
lightControl.off();
projector.on();
dvdPlayer.on();
soundSystem.on();
dvdPlayer.play();
}
}
public class HomeTheaterWithFacade {
public static void main(String[] args) {
DVDPlayer dvdPlayer = new DVDPlayer();
Projector projector = new Projector();
SurroundSoundSystem soundSystem = new SurroundSoundSystem();
CurtainControl curtainControl = new CurtainControl();
LightControl lightControl = new LightControl();
HomeTheaterFacade homeTheater = new HomeTheaterFacade(dvdPlayer, projector, soundSystem, curtainControl, lightControl);
homeTheater.watchMovie();
}
}
解释
在没有使用外观模式的情况下,客户端代码(HomeTheaterWithoutFacade
类中的main
方法)需要直接与各个子系统进行交互,这使得代码变得复杂且难以维护。
使用外观模式后,客户端代码(HomeTheaterWithFacade
类中的main
方法)只需要与外观类(HomeTheaterFacade
)交互。外观类封装了子系统的复杂性,提供了一个简单的接口(watchMovie
方法),从而简化了客户端的操作。这不仅使代码更简洁,还提高了可维护性。比如在 Facade 层(外观模式)提供 add、query、deleteById、modify、queryById 方法,这是一种常见做法。这些方法通常用于提供一个简化的接口,让客户端能够方便地进行基本的 CRUD(创建、读取、更新、删除)操作。
总的来说:外观设计模式所提出的“外观类”的核心思想是将一系列要与复杂系统做的交互提前封装为对应的行为,这样用户就只需要与各式各样的行为进行交互即可,由此屏蔽了系统的复杂性
以上