外观模式白话 - 与中介者、代理模式的区别
前言
外观模式(Facade Pattern)的定义有点让我摸不着头脑
为子系统中的一组接口提供一个统一的入口,通过引入一个外观角色来简化客户端与子系统间的交互,又叫门面模式。属于结构型模式
子系统?客户端?
还交互上了,用的 HTTPS 吗?
设计模式除了帮助我等程序员设计好代码外,还能解决这样的问题?
emmm可能是翻译原因
看看英文
A facade encapsulates a complex subsystem behind a simple interface. It hides much of the complexity and makes the subsystem easy to use
好嘛
确实有subsystem
但没有client
外观模式
个人认为所谓的子系统可以理解成模块,客户端可以理解成模块的使用者
用大白话讲:外观模式通过一个高层接口来封装模块,并按需暴露模块中的方法,从而降低模块使用的复杂度
以电脑开、关机为例
启动电脑(按电源键):启动CPU、启动内存、启动硬盘
关闭电脑(按电源键):关闭硬盘、关闭内存、关闭CPU
如果没有外观(电源键),那流程很复杂:
有外观(电源键)就简单了:
实现
首先定义一个电脑接口并实现它
// 抽象子系统
public interface IComputer {
void start();
void stop();
}
// 子系统1
public class Cpu implements IComputer {
@Override
public void start() {
System.out.println("启动CPU");
}
@Override
public void stop() {
System.out.println("关闭CPU");
}
}
// 子系统2
public class Ddr implements IComputer {
// ...
}
// 子系统3
public class Ssd implements IComputer {
// ...
}
然后定义一个外观角色PowerSwitchFacade
封装功能
public class PowerSwitchFacade {
private IComputer cpu;
private IComputer ddr;
private IComputer ssd;
public PowerSwitchFacade() {
this.cpu = new Cpu();
this.ddr = new Ddr();
this.ssd = new Ssd();
}
public void start() {
this.cpu.start();
this.ddr.start();
this.ssd.start();
}
public void stop() {
this.ssd.stop();
this.ddr.stop();
this.cpu.stop();
}
}
OK,调用一下
// 客户端
public class Client {
public static void main(String[] args) {
PowerSwitchFacade powerSwitchFacade = new PowerSwitchFacade();
powerSwitchFacade.start();
powerSwitchFacade.stop();
}
}
把CPU、内存、硬盘的start()
都封装在powerSwitchFacade.start()
里,客户端开机只需和PowerSwitchFacade
交互,即所谓的降低模块使用的复杂度
原来是你
其实 Java 程序员经常使用外观模式(哈哈哈没想到吧)
Java 的三层开发模式DAO->Service->Controller
就体现了外观模式的思想
回忆下
基于 Spring 开发时会把 DAO、Service、Controller 注入为Bean
作为单例使用
同样的
在外观模式中,通常只需要一个外观类,即它是一个单例
但不等同于整个系统中只有一个外观类哈想想你的 SpringBoot 项目里有多少个 Service 吧骚年~
与中介者模式、代理模式的区别
外观模式在客户端和子系统间增加了一个 Facade 外观角色
看字面意思,这个外观角色挺像个中介者或者代理的
它们仨有啥区别呢?
外观模式:针对客户端和子系统之间,通过一个高层接口简化客户端访问子系统的复杂度
中介者模式:针对子系统内部模块之间,通过一个中介者简化各对象间的相互引用
代理模式:针对单个类,用一个类代表另一个类的功能
总结
外观模式有它的优点:
- 它把需要暴露的功能集中在
Facade
中,隐藏了内部细节,使子系统更加易用 - 客户端不再需要了解子系统内部的实现,而且单个子系统改动不会影响到客户端
Java 的三层开发模式DAO->Service->Controller
就体现了外观模式的思想
外观模式也有缺点,它不符合开闭原则:新增或删减子系统都会影响到Facade
当然,如果开发需要的话也可以直接使用复杂的subsystem,没有强制说是一定得用外观模式,活学活用最重要~
感谢阅读~不喜勿喷。欢迎讨论、指正
转载自:https://juejin.cn/post/7223410490764197925