外观模式(门面模式)
认识:外观模式也叫做门面模式。他的特点就是可以将复杂的系统调用进行封装起来,使用一个中间者对它进行管理,方便外部的调用者对它进行方便的调用。比如,在网站中的前端页面,就是一个门户系统,该门户封装了很多系统复杂的功能,用户(客户端)只需要对需要的功能进行点击,就可以实现在系统的背后进行一系列的操作。
特点:简单调用,提高了系统的安全性,功能层次之间进行了孤立,避免水平低下的程序员对功能的破坏;但是,该模式不符合开闭原则,也就是说,如果我要进行修改或者添加新的接口的话,就需要对代码进行做出较多的改变与调用,不便。
常见场景:SpringMVC的三层架构,Mapper层封装了很多对数据库的操作,Service层封装了很多对Mapper层的封装,Controller层封装了很多对Service层的封装,只关注我自己需要的,不关注其他不重要的。
例子:小明去医院看病,这个看病的过程大致可以分为三个阶段:预约、门诊、取药。如果不使用外观模式的话,那么就需要患者把这三件事情都要一个个的执行,优点麻烦,而且大家都知道,在医院看病有的时候也是比较复杂的,而要是使用外观模式,就是在患者和医院之间建立了一个中间者,比如就是护士,这个护士看见患者来了之后,会帮助患者做好一系列的事情,而患者只需要与护士交互就行了,很便利。
比如,以下就是没有外观模式的案例代码:
/** * @Description: 外观模式之预约功能 * @Author: huidou 惠豆 * @CreateTime: 2022/6/14 16:42 */ public class MakeAnAppointment { /** * 前期 */ public void prepare() { System.out.println("预约---前期工作..."); } /** * 处理 */ public void post() { System.out.println("预约---处理工作..."); } /** * 完成 */ public void after() { System.out.println("预约---完成工作..."); } }
/** * @Description: 外观模式之门诊功能 * @Author: huidou 惠豆 * @CreateTime: 2022/6/14 16:44 */ public class OutpatientDepartment { /** * 前期 */ public void prepare() { System.out.println("处理---前期工作..."); } /** * 处理 */ public void post() { System.out.println("处理---处理工作..."); } /** * 完成 */ public void after() { System.out.println("处理---完成工作..."); } }
/** * @Description: 外观模式之取药功能 * @Author: huidou 惠豆 * @CreateTime: 2022/6/14 16:45 */ public class TakeMedicine { /** * 前期 */ public void prepare() { System.out.println("取药---前期工作..."); } /** * 处理 */ public void post() { System.out.println("取药---处理工作..."); } /** * 完成 */ public void after() { System.out.println("取药---完成工作..."); } }
/** * @Description: 外观模式---主模式(不使用外观模式的调用) * @Author: huidou 惠豆 * @CreateTime: 2022/6/14 16:46 */ public class Main { public static void main(String[] args) { NotUseFacade(); } // 不使用外观模式 public static void NotUseFacade() { // 1、预约对象 MakeAnAppointment makeAnAppointment = new MakeAnAppointment(); // 2、处理对象 OutpatientDepartment outpatientDepartment = new OutpatientDepartment(); // 3、完成对象 TakeMedicine takeMedicine = new TakeMedicine(); // 预约 makeAnAppointment.prepare(); makeAnAppointment.post(); makeAnAppointment.after(); // 处理 outpatientDepartment.prepare(); outpatientDepartment.post(); outpatientDepartment.after(); // 取药 takeMedicine.prepare(); takeMedicine.post(); takeMedicine.after(); } }结果:
从主方法的方法调用就可以看出来,不适用外观模式,这些工作都是需要患者自己去执行的,很麻烦,要是那个步骤没有按照顺序来,就不能顺利的看完病。但是使用外观模式就能很好的解决这个问题。
使用外观模式案例代码如下:
/** * @Description: 外观模式创建一个中间服务封装者 * @Author: huidou 惠豆 * @CreateTime: 2022/6/14 17:39 */ public class FacadeImplement { // 1、预约对象 MakeAnAppointment makeAnAppointment = new MakeAnAppointment(); // 2、处理对象 OutpatientDepartment outpatientDepartment = new OutpatientDepartment(); // 3、完成对象 TakeMedicine takeMedicine = new TakeMedicine(); // 预约 public void makeAnAppointmentFunction() { makeAnAppointment.prepare(); makeAnAppointment.post(); makeAnAppointment.after(); } // 门诊 public void outpatientDepartmentFunction() { outpatientDepartment.prepare(); outpatientDepartment.post(); outpatientDepartment.after(); } // 取药 public void takeMedicineFunction() { takeMedicine.prepare(); takeMedicine.post(); takeMedicine.after(); } }
/** * @Description: 外观模式---主模式(不使用外观模式的调用) * @Author: huidou 惠豆 * @CreateTime: 2022/6/14 16:46 */ public class Main { public static void main(String[] args) { // NotUseFacade(); UseFacade(); } // 使用外观模式 public static void UseFacade() { FacadeImplement facadeImplement = new FacadeImplement(); facadeImplement.makeAnAppointmentFunction(); facadeImplement.outpatientDepartmentFunction(); facadeImplement.takeMedicineFunction(); } }结果还是一样,但是从主方法的调用上来看,少了很多的调用(就相当于只需要与护士做交互即可,其余的事情不用管):
思考:
外观模式感觉他就是一个思想,就是把复杂的调用使用中间者封装起来,外部只需要调用一个简单的中间接口即可。通过中间者进行操作,就像是一个使用了代理模式思想一样。