工作五年了,居然还不懂 门面模式!
好啦,进入我们的主题,今天我给大家分享设计模式中的门面模式
。用贴切的生活故事,以及真实项目场景来讲设计模式
,最后用一句话来总结这个设计模式。
故事
开发的朋友都知道,后端开发通常都是:
controller---servie---dao/mapper/repository
但是,我问过很多人,熟悉门面模式不?有的工作五年了都不知道。
今天老田,就带你来看看门面模式。
门面模式概述
门面模式(Facade Pattern
)又叫作外观模式,提供了一个统一的接口,用来访问子系统中的一群接口。其主要特征是定义了一个高层接口,让子系统更容易使用,属于结构型设计模式。
英文:
Provide a unified interface to a set of interfaces in asubsystem.Facade defines a higher-level interface that makes thesubsystem easier to use.
其实,在日常编码工作中,我们都在有意无意地大量使用门面模式。但凡只要高层模块需要调度多个子系统(2个以上类对象),我们都会自觉地创建一个新类封装这些子系统,提供精简的接口,让高层模块可以更加容易地间接调用这些子系统的功能。
生活中的案例
关于门面模式,在生活中的案例,非常之多。
案例1:去银行办理业务,有个前台接待你,然后,这个前台会问你需要办什么业务,他会一个一个带你办理,这样我们就不需要到处乱串、到处找对应业务窗口了。这个前台人员就相当于门面模式。
案例2:我们建房子,如果没有包工头的话,那就是你自己要去找水泥工,电工、装修工等。但如果有了包工头,这些活你都不用干了,直接跟包工头说,需要电工来把线路搞好。这个包工头就可以理解为门面模式。
案例3:我们后端开发的controller
,也可以理解为门面模式,比如说获取用户账户信息,先查UserService
获取用户信息,然后查UserAccountService
用户账户信息。
门面模式适用场景
在软件系统中,门面模式适用于以下应用场景。
- 为一个复杂的模块或子系统提供一个简洁的供外界访问的接口。
- 希望提高子系统的独立性时。
- 当子系统由于不可避免的暂时原因导致可能存在Bug或性能相关问题时,可以通过门面模式提供一个高层接口,隔离客户端与子系统的直接交互,预防代码污染。
门面模式通用写法
还是使用代码来实现一个简单的门面模式,因为咱们最喜欢的就是从demo开始。
业务场景:现在需要调用三个service的各自的方法:
public class ServiceA { public void doA(){ System.out.println("do ServiceA"); } } public class ServiceB { public void doB(){ System.out.println("do ServiceB"); } } public class ServiceC { public void doC(){ System.out.println("do ServiceC"); } }登录后复制
public class Client { public static void main(String[] args) { ServiceA serviceA=new ServiceA(); ServiceB serviceB=new ServiceB(); ServiceC serviceC=new ServiceC(); serviceA.doA(); serviceB.doB(); serviceC.doC(); } }登录后复制
运行结果
do ServiceA do ServiceB do ServiceC登录后复制登录后复制
public class Facade { //是不是很像我们controller里注入各种service? private ServiceA serviceA = new ServiceA(); private ServiceB serviceB = new ServiceB(); private ServiceC serviceC = new ServiceC(); public void doA() { serviceA.doA(); } public void doB() { serviceB.doB(); } public void doC() { serviceC.doC(); } }登录后复制
public class Client { public static void main(String[] args) { //轻轻松松的搞定,只需要创建门面这个对象即可 Facade facade=new Facade(); facade.doA(); facade.doB(); facade.doC(); } }登录后复制
do ServiceA do ServiceB do ServiceC登录后复制登录后复制