外观模式(门面模式)
认识:外观模式也叫做门面模式。他的特点就是可以将复杂的系统调用进行封装起来,使用一个中间者对它进行管理,方便外部的调用者对它进行方便的调用。比如,在网站中的前端页面,就是一个门户系统,该门户封装了很多系统复杂的功能,用户(客户端)只需要对需要的功能进行点击,就可以实现在系统的背后进行一系列的操作。
特点:简单调用,提高了系统的安全性,功能层次之间进行了孤立,避免水平低下的程序员对功能的破坏;但是,该模式不符合开闭原则,也就是说,如果我要进行修改或者添加新的接口的话,就需要对代码进行做出较多的改变与调用,不便。
常见场景: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();
}
}
结果还是一样,但是从主方法的调用上来看,少了很多的调用(就相当于只需要与护士做交互即可,其余的事情不用管):思考:
外观模式感觉他就是一个思想,就是把复杂的调用使用中间者封装起来,外部只需要调用一个简单的中间接口即可。通过中间者进行操作,就像是一个使用了代理模式思想一样。
查看9道真题和解析