设计模式---门面模式
设计模式——门面模式
一、什么是门面模式?
门面模式(Facade Pattern)是一种结构型设计模式,它的核心思想是:为复杂的子系统提供一个统一的入口。
你可以把它理解为“前台”或者“客服”。
- 在公司里,客户不会直接去找财务、技术、仓库,而是先联系前台或者客服。
- 前台(门面类)接收请求,然后在内部协调各个部门(子系统类),最后给客户一个结果。
这样一来,客户只需要面对“一个接口”,而不用了解背后复杂的流程。
二、为什么需要门面模式?
假设我们在做一个家庭影院系统,它有很多设备:
- DVD 播放器
- 投影仪
- 音响
- 灯光
如果客户想看一场电影,需要按顺序做很多操作:
- 打开灯光并调暗
- 打开投影仪并调成宽屏模式
- 打开音响并设置音量
- 打开 DVD 并播放电影
当电影结束,还需要按顺序关闭所有设备。
如果让客户端自己调用这些子系统的接口,会非常繁琐,也容易出错。
这时,我们就可以用门面模式,封装一套“简化操作”的接口:
watchMovie()
:一键开始电影endMovie()
:一键关闭影院
这样,客户端只需要调用两行代码,背后复杂的流程全部由门面类完成。
三、代码示例(Java 实现)
1. 子系统类
// DVD 播放器
class DVDPlayer {public void on() { System.out.println("DVD 打开"); }public void play(String movie) { System.out.println("播放电影: " + movie); }public void off() { System.out.println("DVD 关闭"); }
}// 投影仪
class Projector {public void on() { System.out.println("投影仪 打开"); }public void wideScreenMode() { System.out.println("投影仪设置为宽屏模式"); }public void off() { System.out.println("投影仪 关闭"); }
}// 音响
class SoundSystem {public void on() { System.out.println("音响 打开"); }public void setVolume(int level) { System.out.println("音量设置为: " + level); }public void off() { System.out.println("音响 关闭"); }
}// 灯光
class Light {public void dim(int level) { System.out.println("灯光调暗到: " + level + "%"); }public void on() { System.out.println("灯光恢复正常亮度"); }
}
2. 门面类(统一入口)
class HomeTheaterFacade {private DVDPlayer dvd;private Projector projector;private SoundSystem sound;private Light light;public HomeTheaterFacade(DVDPlayer dvd, Projector projector, SoundSystem sound, Light light) {this.dvd = dvd;this.projector = projector;this.sound = sound;this.light = light;}// 一键启动影院public void watchMovie(String movie) {System.out.println("准备开始看电影...");light.dim(10);projector.on();projector.wideScreenMode();sound.on();sound.setVolume(20);dvd.on();dvd.play(movie);}// 一键关闭影院public void endMovie() {System.out.println("关闭影院...");dvd.off();sound.off();projector.off();light.on();}
}
3. 客户端调用
public class FacadeDemo {public static void main(String[] args) {// 创建子系统对象DVDPlayer dvd = new DVDPlayer();Projector projector = new Projector();SoundSystem sound = new SoundSystem();Light light = new Light();// 创建门面对象HomeTheaterFacade homeTheater = new HomeTheaterFacade(dvd, projector, sound, light);// 客户端只需要两行代码homeTheater.watchMovie("《731电影》");homeTheater.endMovie();}
}
4. 运行结果
准备开始看电影...
灯光调暗到: 10%
投影仪 打开
投影仪设置为宽屏模式
音响 打开
音量设置为: 20
DVD 打开
播放电影: 《731电影》
关闭影院...
DVD 关闭
音响 关闭
投影仪 关闭
灯光恢复正常亮度
四、门面模式的优缺点
优点
- 简化调用:客户端不用了解复杂的子系统,只需要面对一个统一的接口。
- 解耦:降低了客户端与子系统之间的依赖。
- 易维护:修改子系统时,只要保持门面接口不变,客户端就不受影响。
缺点
- 复杂:如果门面类功能越来越多,会变得臃肿。
- 不够灵活:有些特殊需求,可能还需要绕过门面直接操作子系统。
五、应用场景
- 复杂系统提供简化接口:比如数据库访问,Spring 提供了
JdbcTemplate
,只要写几行代码就能执行 SQL,而不用自己写 JDBC 的连接、关闭等繁琐逻辑。 - 一键操作:如电脑的“电源键”,背后其实涉及 CPU、内存、风扇、操作系统启动等复杂过程。
- 统一入口:像银行柜台、公司前台,都是门面模式的典型应用。
六、总结
门面模式的精髓是:
在复杂系统和客户端之间,提供一个简单的入口,让客户端更轻松地使用系统。
在实际开发中,我们经常会遇到系统复杂、调用繁琐的情况。此时,如果能为它们设计一个“门面类”,不仅能让客户端更好用,还能降低耦合,提升系统的可维护性。
一句话总结:
门面模式就是帮客户节省时间的“客服”,而不是让客户自己在后厨乱找。